{"id":489628,"date":"2026-08-03T23:09:13","date_gmt":"2026-08-03T23:09:13","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=489628"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=489628","title":{"rendered":"Wiremokjs \u043a\u0430\u043a \u044f \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b \u0441\u0432\u043e\u0439 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u044b\u0439 \u044f\u0437\u044b\u043a \u0434\u043b\u044f wiremock"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u044b\u0439 \u044f\u0437\u044b\u043a <strong>WiremockJs<\/strong> \u2014 \u0441 \u043d\u0443\u043b\u044f \u0438 \u0434\u043e \u0440\u0430\u0431\u043e\u0447\u0435\u0433\u043e \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u0430. \u041f\u043e\u0434\u0435\u043b\u044e\u0441\u044c, \u0447\u0442\u043e \u043c\u0435\u043d\u044f \u043f\u043e\u0434\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u043e \u043a \u044d\u0442\u043e\u043c\u0443 \u00ab\u043f\u043e\u0434\u0432\u0438\u0433\u0443\u00bb, \u043a\u0430\u043a \u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043b \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0443, \u0441 \u043a\u0430\u043a\u0438\u043c\u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f\u043c\u0438 \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f \u0438 \u043f\u043e\u0447\u0435\u043c\u0443 \u0432 \u0438\u0442\u043e\u0433\u0435 \u043d\u0435 \u0441\u0442\u0430\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c JavaScript, \u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u0441\u0432\u043e\u0439 \u0443\u043f\u0440\u043e\u0449\u0451\u043d\u043d\u044b\u0439 \u0434\u0438\u0430\u043b\u0435\u043a\u0442. \u041f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c \u2014 ANTLR, \u043f\u0430\u0440\u0441\u0435\u0440\u044b, \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0431\u043e\u043b\u0438 \u0438 \u043c\u043d\u043e\u0433\u043e \u0443\u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u0438\u044f \u043e\u0442 \u0442\u0432\u043e\u0440\u0447\u0435\u0441\u0442\u0432\u0430.<\/p>\n<h3>\u041e\u0433\u043b\u0430\u0432\u043b\u0435\u043d\u0438\u0435<\/h3>\n<ol>\n<li>\n<p><a href=\"#predislovie-kak-vsyo-nachinalos\" rel=\"noopener noreferrer nofollow\">\u041f\u0440\u0435\u0434\u0438\u0441\u043b\u043e\u0432\u0438\u0435: \u043a\u0430\u043a \u0432\u0441\u0451 \u043d\u0430\u0447\u0438\u043d\u0430\u043b\u043e\u0441\u044c<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#na-chem-ya-ostanovilsya-v-proshlyy-raz\" rel=\"noopener noreferrer nofollow\">\u041d\u0430 \u0447\u0451\u043c \u044f \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0441\u044f \u0432 \u043f\u0440\u043e\u0448\u043b\u044b\u0439 \u0440\u0430\u0437?<\/a> <\/p>\n<ul>\n<li>\n<p><a href=\"#sravnenie-grammatik-bylo-i-stalo\" rel=\"noopener noreferrer nofollow\">\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a \u0431\u044b\u043b\u043e \u0438 \u0441\u0442\u0430\u043b\u043e<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#grammaticheskie-pravila\" rel=\"noopener noreferrer nofollow\">\u0413\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#leksicheskie-tokeny\" rel=\"noopener noreferrer nofollow\">\u041b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0442\u043e\u043a\u0435\u043d\u044b<\/a><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><a href=\"#visitor-kak-derevo-razbora-prevraschaetsya-v-rezultat\" rel=\"noopener noreferrer nofollow\">Visitor: \u043a\u0430\u043a \u0434\u0435\u0440\u0435\u0432\u043e \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#kak-wiremock-uznaet-pro-rasshirenie\" rel=\"noopener noreferrer nofollow\">\u041a\u0430\u043a WireMock \u0443\u0437\u043d\u0430\u0451\u0442 \u043f\u0440\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435?<\/a> <\/p>\n<ul>\n<li>\n<p><a href=\"#tochka-vhoda-transform\" rel=\"noopener noreferrer nofollow\">\u0422\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430: transform()<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#zaschita-ot-zavisaniy-taymaut-vypolneniya\" rel=\"noopener noreferrer nofollow\">\u0417\u0430\u0449\u0438\u0442\u0430 \u043e\u0442 \u0437\u0430\u0432\u0438\u0441\u0430\u043d\u0438\u0439: \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f<\/a><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><a href=\"#zachem-nuzhen-requestfacade\" rel=\"noopener noreferrer nofollow\">\u0417\u0430\u0447\u0435\u043c \u043d\u0443\u0436\u0435\u043d RequestFacade?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#scriptguard-pervaya-liniya-zaschity-do-antlr\" rel=\"noopener noreferrer nofollow\">ScriptGuard: \u043f\u0435\u0440\u0432\u0430\u044f \u043b\u0438\u043d\u0438\u044f \u0437\u0430\u0449\u0438\u0442\u044b \u0434\u043e ANTLR<\/a> <\/p>\n<ul>\n<li>\n<p><a href=\"#dva-momenta-vyzova-na-vhode-i-na-ispolnenii\" rel=\"noopener noreferrer nofollow\">\u0414\u0432\u0430 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0432\u044b\u0437\u043e\u0432\u0430 \u2014 \u043d\u0430 \u0432\u0445\u043e\u0434\u0435 \u0438 \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438<\/a><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><a href=\"#administrirovanie-i-operacii-so-skriptami\" rel=\"noopener noreferrer nofollow\">\u0410\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430\u043c\u0438<\/a> <\/p>\n<ul>\n<li>\n<p><a href=\"#dobavlenie-skriptov\" rel=\"noopener noreferrer nofollow\">\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432:<\/a><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><a href=\"#funkcii\" rel=\"noopener noreferrer nofollow\">\u0424\u0443\u043d\u043a\u0446\u0438\u0438<\/a> <\/p>\n<ul>\n<li>\n<p><a href=\"#jsonfield-path\" rel=\"noopener noreferrer nofollow\">jsonField(path)<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#daty-cherez-java-time-a-ne-vruchnuyu\" rel=\"noopener noreferrer nofollow\">\u0414\u0430\u0442\u044b \u0447\u0435\u0440\u0435\u0437 java.time, \u0430 \u043d\u0435 \u0432\u0440\u0443\u0447\u043d\u0443\u044e<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#uuid-i-randomint-s-oglyadkoy-na-determinizm\" rel=\"noopener noreferrer nofollow\">uuid() \u0438 randomInt() \u2014 \u0441 \u043e\u0433\u043b\u044f\u0434\u043a\u043e\u0439 \u043d\u0430 \u0434\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0438\u0437\u043c<\/a> <\/p>\n<ul>\n<li>\n<p><a href=\"#zachem-seed-nuzhen-imenno-v-wiremockjs\" rel=\"noopener noreferrer nofollow\">\u0417\u0430\u0447\u0435\u043c seed \u043d\u0443\u0436\u0435\u043d \u0438\u043c\u0435\u043d\u043d\u043e \u0432 WiremockJs<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#shag-1-sozdaem-skript-s-seed\" rel=\"noopener noreferrer nofollow\">\u0428\u0430\u0433 1 \u2014 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u043a\u0440\u0438\u043f\u0442 \u0441 seed<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#shag-2-sozdaem-stab-privyazannyy-k-skriptu\" rel=\"noopener noreferrer nofollow\">\u0428\u0430\u0433 2 \u2014 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u0442\u0430\u0431, \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0439 \u043a \u0441\u043a\u0440\u0438\u043f\u0442\u0443<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#shag-3-vyzyvaem-stab-neskolko-raz\" rel=\"noopener noreferrer nofollow\">\u0428\u0430\u0433 3 \u2014 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0441\u0442\u0430\u0431 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#kak-eto-vedet-sebya-na-praktike\" rel=\"noopener noreferrer nofollow\">\u041a\u0430\u043a \u044d\u0442\u043e \u0432\u0435\u0434\u0451\u0442 \u0441\u0435\u0431\u044f \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435<\/a><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><a href=\"#matches-str-pattern\" rel=\"noopener noreferrer nofollow\">matches(str, pattern)<\/a> <\/p>\n<ul>\n<li>\n<p><a href=\"#primer-1-validaciya-formata-telefona-pered-obrabotkoy-zakaza\" rel=\"noopener noreferrer nofollow\">\u041f\u0440\u0438\u043c\u0435\u0440 1 \u2014 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u0444\u043e\u0440\u043c\u0430\u0442\u0430 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430 \u043f\u0435\u0440\u0435\u0434 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 \u0437\u0430\u043a\u0430\u0437\u0430<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#primer-2-bolee-slozhnyy-primer-v-kotorom-realizovana-marshrutizaciya-po-neskolkim-formatam-telefona\" rel=\"noopener noreferrer nofollow\">\u041f\u0440\u0438\u043c\u0435\u0440 2 &#8212; \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0430\u043c \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#zachem-ponadobilsya-re2j\" rel=\"noopener noreferrer nofollow\">\u0417\u0430\u0447\u0435\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u043b\u0441\u044f RE2J<\/a><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><a href=\"#fake-zaglushka-dlya-realistichnyh-dannyh\" rel=\"noopener noreferrer nofollow\">fake() \u2014 \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0430 \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0441\u0442\u0438\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445<\/a> <\/p>\n<ul>\n<li>\n<p><a href=\"#primer-1-prostaya-generaciya-klienta\" rel=\"noopener noreferrer nofollow\">\u041f\u0440\u0438\u043c\u0435\u0440 1 \u2014 \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#primer-2-determinirovannyy-feykovyy-zakaz-cherez-seed\" rel=\"noopener noreferrer nofollow\">\u041f\u0440\u0438\u043c\u0435\u0440 2 \u2014 \u0434\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0444\u0435\u0439\u043a\u043e\u0432\u044b\u0439 \u0437\u0430\u043a\u0430\u0437 \u0447\u0435\u0440\u0435\u0437 seed<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#primer-3-sochetanie-fake-s-realnymi-dannymi-iz-zaprosa\" rel=\"noopener noreferrer nofollow\">\u041f\u0440\u0438\u043c\u0435\u0440 3 \u2014 \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0435 fake() \u0441 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438\u0437 \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#poleznye-shablony-datafaker-dlya-spravki\" rel=\"noopener noreferrer nofollow\">\u041f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u044b DataFaker \u0434\u043b\u044f \u0441\u043f\u0440\u0430\u0432\u043a\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#kombinirovanie-neskolkih-znacheniy-v-odnom-vyzove\" rel=\"noopener noreferrer nofollow\">\u041a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0432 \u043e\u0434\u043d\u043e\u043c \u0432\u044b\u0437\u043e\u0432\u0435<\/a><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><a href=\"#mapkeys-pereimenovanie-poley-bez-polnocennogo-eval\" rel=\"noopener noreferrer nofollow\">mapKeys() \u2014 \u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u0435\u0439 \u0431\u0435\u0437 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0433\u043e eval<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#agregirovannye-funkcii\" rel=\"noopener noreferrer nofollow\">\u0410\u0433\u0440\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/a> <\/p>\n<ul>\n<li>\n<p><a href=\"#pochemu-agregirovannye-funkcii\" rel=\"noopener noreferrer nofollow\">\u041f\u043e\u0447\u0435\u043c\u0443 \u0430\u0433\u0440\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#kak-eto-rabotaet-pod-kapotom\" rel=\"noopener noreferrer nofollow\">\u041a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#primer-1-summa-i-kolichestvo-tovarov-v-zakaze\" rel=\"noopener noreferrer nofollow\">\u041f\u0440\u0438\u043c\u0435\u0440 1 \u2014 \u0441\u0443\u043c\u043c\u0430 \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0442\u043e\u0432\u0430\u0440\u043e\u0432 \u0432 \u0437\u0430\u043a\u0430\u0437\u0435<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#primer-2-sredniy-chek-s-proverkoy-na-pustoy-zakaz\" rel=\"noopener noreferrer nofollow\">\u041f\u0440\u0438\u043c\u0435\u0440 2 \u2014 \u0441\u0440\u0435\u0434\u043d\u0438\u0439 \u0447\u0435\u043a \u0441 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439 \u043d\u0430 \u043f\u0443\u0441\u0442\u043e\u0439 \u0437\u0430\u043a\u0430\u0437<\/a><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><a href=\"#foreach-po-massivu\" rel=\"noopener noreferrer nofollow\">ForEach \u043f\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0443<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#gde-togda-mesto-sum-count-avg-ryadom-s-foreach\" rel=\"noopener noreferrer nofollow\">\u0413\u0434\u0435 \u0442\u043e\u0433\u0434\u0430 \u043c\u0435\u0441\u0442\u043e sum\/count\/avg \u0440\u044f\u0434\u043e\u043c \u0441 forEach<\/a><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><a href=\"#limity\" rel=\"noopener noreferrer nofollow\">\u041b\u0438\u043c\u0438\u0442\u044b<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#hronologiya-problem\" rel=\"noopener noreferrer nofollow\">\u0425\u0440\u043e\u043d\u043e\u043b\u043e\u0433\u0438\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#zapustk-wiremock-s-rasshireniem\" rel=\"noopener noreferrer nofollow\">\u0417\u0430\u043f\u0443\u0441\u0442\u043a Wiremock \u0441 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435\u043c<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#zaklyuchenie\" rel=\"noopener noreferrer nofollow\">\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#ssylki\" rel=\"noopener noreferrer nofollow\">\u0421\u0441\u044b\u043b\u043a\u0438<\/a><\/p>\n<\/li>\n<\/ol>\n<hr\/>\n<p><a class=\"anchor\" name=\"predislovie-kak-vsyo-nachinalos\" id=\"predislovie-kak-vsyo-nachinalos\"><\/a><\/p>\n<h3>\u041f\u0440\u0435\u0434\u0438\u0441\u043b\u043e\u0432\u0438\u0435. \u041a\u0430\u043a \u0432\u0441\u0451 \u043d\u0430\u0447\u0438\u043d\u0430\u043b\u043e\u0441\u044c<\/h3>\n<p>\u041f\u0430\u0440\u0443 \u043c\u0435\u0441\u044f\u0446\u0435\u0432 \u043d\u0430\u0437\u0430\u0434 \u044f \u0441\u0434\u0435\u043b\u0430\u043b UI \u0434\u043b\u044f WireMock. \u0412 \u043d\u0435\u0433\u043e \u0432\u043e\u0448\u043b\u043e \u0432\u0441\u0451, \u0447\u0442\u043e \u044f \u0442\u043e\u0433\u0434\u0430 \u0443\u0441\u043f\u0435\u043b:<\/p>\n<ul>\n<li>\n<p>\u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0441\u0442\u0430\u0431\u043e\u0432,<\/p>\n<\/li>\n<li>\n<p>\u0443\u0434\u043e\u0431\u043d\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e API \u0441 \u043f\u043e\u0438\u0441\u043a\u043e\u043c \u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0435\u0439,<\/p>\n<\/li>\n<li>\n<p>\u0432\u044b\u0437\u043e\u0432 \u0441\u0442\u0430\u0431\u0430 \u043f\u0440\u044f\u043c\u043e \u0438\u0437 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 (\u0431\u0435\u0437 Postman),<\/p>\n<\/li>\n<li>\n<p>\u0438\u0441\u0442\u043e\u0440\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0432\u043a\u043b\u0430\u0434\u043a\u0435,<\/p>\n<\/li>\n<li>\n<p>\u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u043c\u043e\u043a\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u0431\u043e\u0432 \u043f\u043e openApi \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u043e \u0433\u043b\u0430\u0432\u043d\u043e\u0435, \u0447\u0442\u043e \u0438\u0437\u0431\u0430\u0432\u0438\u043b\u043e \u043c\u0435\u043d\u044f \u043e\u0442 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0439 \u0433\u043e\u043b\u043e\u0432\u043d\u043e\u0439 \u0431\u043e\u043b\u0438 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u043c\u0435\u0436\u0434\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u043c\u0438, \u2014 <strong>\u043f\u0440\u043e\u0444\u0438\u043b\u0438<\/strong>. \u0417\u0430\u0433\u0440\u0443\u0437\u0438\u043b \u043d\u0443\u0436\u043d\u044b\u0439 \u043f\u0440\u043e\u0444\u0438\u043b\u044c \u2014 \u0438 \u0432\u0441\u0435 \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0438 \u0443\u0436\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u044b, \u043d\u0435 \u043d\u0430\u0434\u043e \u0434\u0443\u043c\u0430\u0442\u044c \u043e \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0430\u0445 \u0438 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f\u0445 \u0440\u0443\u0447\u0435\u043a. \u041a\u0441\u0442\u0430\u0442\u0438, \u043c\u043d\u043e\u0433\u0438\u0435 UI \u043f\u044b\u0442\u0430\u044e\u0442\u0441\u044f \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043f\u043e\u043a\u0430\u0437 API \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043c\u043e\u043a\u043e\u0432 \u0432 \u043f\u0430\u043f\u043a\u0430\u0445, \u043a\u0430\u043a \u0432 Postman, \u043d\u043e \u044f \u0441\u0447\u0438\u0442\u0430\u044e \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0443\u0434\u043e\u0431\u043d\u044b\u043c. \u041f\u0440\u043e\u0444\u0438\u043b\u0438 \u043e\u043a\u0430\u0437\u0430\u043b\u0438\u0441\u044c \u043f\u0440\u043e\u0449\u0435 \u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u043d\u0435\u0435.<\/p>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u2013 \u044d\u0442\u043e \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432. \u0411\u044b\u043b\u043e \u043d\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0430 \u0432\u044b\u0437\u0432\u0430\u043b\u0441\u044f \u043b\u0438 \u0437\u0430\u043f\u0440\u043e\u0441? \u0410 \u0447\u0442\u043e \u043f\u0440\u0438\u0448\u043b\u043e \u0438 \u043a\u043e\u0433\u0434\u0430?<\/p>\n<p>\u0422\u0440\u0435\u0442\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0438 \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435 \u0441\u0430\u043c\u043e\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u044d\u0442\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0438. \u041f\u043e\u0447\u0435\u043c\u0443-\u0442\u043e \u0441 \u0432\u043e\u043f\u0440\u043e\u0441\u0430\u043c\u0438 \u043f\u043e \u043c\u043e\u043a\u0430\u043c \u043e\u043d\u0438 \u0448\u043b\u0438 \u0438\u043c\u0435\u043d\u043d\u043e \u043a\u043e \u043c\u043d\u0435. \u041f\u043e\u0441\u043b\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0434\u043d\u0435\u0439 \u043a\u043e\u043b\u043b\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u044f \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u0442\u0430\u043a \u0434\u0430\u043b\u044c\u0448\u0435 \u043d\u0435\u043b\u044c\u0437\u044f. \u0412\u043e\u2011\u043f\u0435\u0440\u0432\u044b\u0445, \u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, \u0430 \u043d\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0449\u0438\u043a. \u0412\u043e\u2011\u0432\u0442\u043e\u0440\u044b\u0445, \u044f \u043d\u0435 \u043c\u043e\u0433\u0443 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e \u043e\u0431\u0443\u0447\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0445 \u0441\u043e\u0442\u0440\u0443\u0434\u043d\u0438\u043a\u043e\u0432 \u043d\u044e\u0430\u043d\u0441\u0430\u043c WireMock, MockServer \u0438 JSON. \u041b\u044e\u0434\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0438 \u0443\u0445\u043e\u0434\u044f\u0442, \u0430 \u0432\u0440\u0435\u043c\u044f \u043d\u0430 \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u044f \u0443\u0445\u043e\u0434\u0438\u0442 \u043a\u043e\u043b\u043e\u0441\u0441\u0430\u043b\u044c\u043d\u043e\u0435. \u041f\u043b\u044e\u0441 \u044f \u0441\u0430\u043c \u0437\u0430\u0431\u044b\u0432\u0430\u044e \u0447\u0442\u043e \u044f \u0442\u0430\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b \u0438 \u043a\u0430\u043a \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u043b. \u041c\u043d\u0435 \u043d\u0435\u0445\u0432\u0430\u0442\u0430\u043b\u043e \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430. \u041f\u0440\u043e\u0448\u0435\u043b\u0441\u044f \u043f\u043e \u0448\u0430\u0433\u0430\u043c \u0438 \u0432\u0441\u0435 \u0433\u043e\u0442\u043e\u0432\u043e. \u041d\u0435 \u043d\u0430\u0434\u043e \u0434\u0443\u043c\u0430\u0442\u044c, \u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043b\u0438 \u0442\u044b \u0441\u043e\u0437\u0434\u0430\u043b json.<\/p>\n<p>\u0412\u044b \u0441\u043f\u0440\u043e\u0441\u0438\u0442\u0435: \u043f\u043e\u0447\u0435\u043c\u0443 \u043d\u0435 \u0432\u0437\u044f\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f WireMock? \u0422\u0443\u0442 \u043f\u0440\u0438\u0447\u0438\u043d\u0430 \u0432\u043e \u043c\u043d\u0435, \u043c\u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u043a\u043e\u043f\u0430\u0442\u044c\u0441\u044f \u0438 \u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0441\u0451 \u043f\u043e\u0434 \u0441\u0435\u0431\u044f, \u0442\u0430\u043a, \u043a\u0430\u043a \u044f \u0441\u0447\u0438\u0442\u0430\u044e \u0443\u0434\u043e\u0431\u043d\u044b\u043c. \u041d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u0438\u0434\u0438\u0440\u0447\u0438\u0432 \u043a \u0447\u0443\u0436\u0438\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u043c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438 \u0440\u0435\u0448\u0438\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0451.<\/p>\n<p>\u0426\u0435\u043d\u0438\u0442 \u043b\u0438 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f \u043c\u0435\u043d\u044f \u0437\u0430 \u0442\u043e, \u0447\u0442\u043e \u044f \u043f\u044b\u0442\u0430\u044e\u0441\u044c \u043f\u0440\u0438\u0432\u043d\u0435\u0441\u0442\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044e \u0438 \u0447\u0442\u043e-\u0442\u043e \u043d\u043e\u0432\u043e\u0435? \u0415\u0441\u043b\u0438 \u0447\u0435\u0441\u0442\u043d\u043e, \u044f \u0443\u0436\u0435 \u0434\u0430\u0432\u043d\u043e \u043d\u0435 \u0437\u0430\u0434\u0430\u044e \u0441\u0435\u0431\u0435 \u044d\u0442\u043e\u0442 \u0432\u043e\u043f\u0440\u043e\u0441. \u042f \u0443\u0436\u0435 \u043f\u0438\u0441\u0430\u043b \u043e\u0431 \u044d\u0442\u043e\u043c \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 (<a href=\"https:\/\/habr.com\/ru\/articles\/1023162\/\" rel=\"noopener noreferrer nofollow\">\u0441\u0441\u044b\u043b\u043a\u0430<\/a>), \u0438 \u043c\u043e\u0439 \u043e\u043f\u044b\u0442 \u0437\u0430 15 \u043b\u0435\u0442 \u0433\u043e\u0432\u043e\u0440\u0438\u0442: \u043d\u0435 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u043b\u044e\u0434\u0438 \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0435\u0451. \u0415\u0441\u043b\u0438 \u043c\u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442 \u0432\u0440\u0435\u043c\u044f, \u044f \u0435\u0433\u043e \u043f\u0438\u043b\u044e. \u0415\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u044b \u0434\u0435\u043d\u044c\u0433\u0438, \u0442\u043e \u043f\u044b\u0442\u0430\u044e\u0441\u044c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0438 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0432\u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u044b. \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043b\u0438? \u041f\u043e\u043a\u0430 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435, \u043d\u043e \u044d\u0442\u043e \u0443\u0436\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0434\u0440\u0443\u0433\u0430\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u044f.<\/p>\n<p>\u0410 \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0432\u044b\u0433\u043e\u0440\u0430\u0442\u044c \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u0435, \u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e \u0441\u0435\u0431\u0435 \u0442\u0430\u043a\u0438\u0435 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0435 \u043f\u0435\u0442-\u043f\u0440\u043e\u0435\u043a\u0442\u044b \u2014 UI \u0438\u043b\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0434\u043b\u044f WireMock. \u041e\u043d\u0438 \u043f\u0440\u0438\u043d\u043e\u0441\u044f\u0442 \u0443\u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u0438\u0435, \u0430 \u0437\u0430\u043e\u0434\u043d\u043e \u044d\u043a\u043e\u043d\u043e\u043c\u044f\u0442 \u0432\u0440\u0435\u043c\u044f \u043d\u0430 \u0442\u0435 \u0437\u0430\u0434\u0430\u0447\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043b\u044e\u0431\u043b\u044e.<\/p>\n<p><a class=\"anchor\" name=\"na-chem-ya-ostanovilsya-v-proshlyy-raz\" id=\"na-chem-ya-ostanovilsya-v-proshlyy-raz\"><\/a><\/p>\n<h3>\u041d\u0430 \u0447\u0451\u043c \u044f \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0441\u044f \u0432 \u043f\u0440\u043e\u0448\u043b\u044b\u0439 \u0440\u0430\u0437?<\/h3>\n<p>\u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 UI \u044f \u043d\u0435 \u0443\u0441\u043f\u0435\u043b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c <strong>\u0441\u043a\u0440\u0438\u043f\u0442\u044b<\/strong>.  \u0414\u043b\u044f \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u043e\u0432 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u044b\u0435 \u0441\u0442\u0430\u0431\u044b, \u0430 \u0433\u0438\u0431\u043a\u0438\u0435 \u043c\u043e\u043a\u0438 \u0441 \u043b\u043e\u0433\u0438\u043a\u043e\u0439. WireMock \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u043d\u0430 Java \u0447\u0435\u0440\u0435\u0437 JAR-\u0444\u0430\u0439\u043b\u044b, \u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043a\u0430\u0437\u0430\u043b\u0441\u044f \u043c\u043d\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0433\u0440\u043e\u043c\u043e\u0437\u0434\u043a\u0438\u043c:<\/p>\n<ul>\n<li>\n<p>\u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0438 \u043f\u0438\u0448\u0443\u0442 \u043d\u0430 Python \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u044f\u0437\u044b\u043a\u0430\u0445, \u043d\u0435 \u0444\u0430\u043a\u0442, \u0447\u0442\u043e \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u043a\u043e\u0434\u0438\u0442\u044c \u043d\u0430 Java;<\/p>\n<\/li>\n<li>\n<p>\u043b\u044e\u0431\u043e\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0441\u0431\u043e\u0440\u043a\u0438, \u0434\u0435\u043f\u043b\u043e\u044f \u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430 WireMock \u2014 \u044d\u0442\u043e \u043c\u0438\u043d\u0443\u0442\u044b, \u0430 \u043d\u0435 \u0441\u0435\u043a\u0443\u043d\u0434\u044b.<\/p>\n<\/li>\n<\/ul>\n<p>\u042f \u043c\u0435\u0447\u0442\u0430\u043b \u043e \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0441\u043a\u0440\u0438\u043f\u0442 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043d\u0430 \u043b\u0435\u0442\u0443 \u0438 \u0441\u0440\u0430\u0437\u0443 \u0432\u0438\u0434\u0435\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u041d\u0443 \u0438 \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0432 \u0442\u0430\u043a\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043d\u0430\u043f\u0438\u0448\u0443\u0442 \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u044b. \u0427\u0442\u043e \u0432 \u0434\u043e\u043b\u0433\u043e\u0441\u0440\u043e\u0447\u043d\u043e\u0439 \u043f\u0435\u0440\u0441\u043f\u0435\u043a\u0442\u0438\u0432\u0435 \u0441\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435.<\/p>\n<p>\u042f \u0441\u0442\u0430\u043b \u0438\u0441\u043a\u0430\u0442\u044c \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u0432 wiremock. \u0418 \u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u0445 \u0434\u043b\u044f \u043c\u043e\u043a\u043e\u0432. \u041d\u0430\u0448\u0435\u043b <a href=\"https:\/\/github.com\/kumarvikas1\/WireMockCoolExtensions\" rel=\"noopener noreferrer nofollow\">WireMockCoolExtensions<\/a>. \u041d\u043e \u0442\u0430\u043c \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u043b\u0441\u044f \u0443\u0436\u0435 10 \u043b\u0435\u0442. \u0414\u0430 \u0438 \u043d\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b \u043e\u043d \u043a\u0430\u043a \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0434\u0443\u043a\u0442. \u0421\u0442\u0430\u043b \u0434\u0443\u043c\u0430\u0442\u044c \u043a\u0430\u043a \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c javascript \u0432 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435, \u043d\u043e \u0442\u0443\u0442 \u0432\u0441\u043f\u043b\u044b\u043b\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b:<\/p>\n<ul>\n<li>\n<p>\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c (\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 JS \u0432 JVM \u2014 \u044d\u0442\u043e \u0440\u0438\u0441\u043a),<\/p>\n<\/li>\n<li>\n<p>\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u043e\u0442 Nashorn (\u0443\u0441\u0442\u0430\u0440\u0435\u043b) \u0438\u043b\u0438 GraalVM Polyglot (\u0442\u044f\u0436\u0451\u043b\u044b\u0439),<\/p>\n<\/li>\n<li>\n<p>WireMock \u0434\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u0441\u0438\u0434\u0438\u0442 \u043d\u0430 Java 11, \u0438 \u043f\u043e\u0434\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438 \u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c.<\/p>\n<\/li>\n<\/ul>\n<p>\u042f \u0432\u0437\u0432\u0435\u0441\u0438\u043b \u0432\u0441\u0451 \u0438 \u0440\u0435\u0448\u0438\u043b: \u0432\u0441\u0435\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 JavaScript \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0437\u0430\u0433\u043b\u0443\u0448\u0435\u043a \u043d\u0435 \u043d\u0443\u0436\u043d\u043e. \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u0439 <strong>\u0443\u043f\u0440\u043e\u0449\u0451\u043d\u043d\u044b\u0439 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u044b\u0439 \u044f\u0437\u044b\u043a<\/strong>. \u041d\u0430\u0437\u0432\u0430\u043b \u0435\u0433\u043e WiremockJs. \u0414\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u0432\u044b\u0431\u0440\u0430\u043b <strong>ANTLR<\/strong> \u2014 \u043c\u043e\u0449\u043d\u044b\u0439 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0435\u043d\u043d\u044b\u0439 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u043f\u0435\u0440\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b\u0430 \u0442\u0430\u043a:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0435\u0440\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>grammar WiremockJs;script    : statement+ EOF    ;statement    : ifStatement    | returnStatement    ;ifStatement    : IF '(' expression ')' '{' thenStmt+=statement+ '}' (ELSE '{' elseStmt+=statement+ '}')?    ;returnStatement    : RETURN expression ';'    ;expression    : expression op=('*'|'\/'|'%') expression        # MulDiv    | expression op=('+'|'-') expression            # AddSub    | expression op=('&gt;'|'&gt;='|'&lt;'|'&lt;=') expression  # Compare    | expression op=('=='|'!=') expression          # Equality    | expression AND expression                     # LogicalAnd    | expression OR expression                      # LogicalOr    | NOT expression                                # LogicalNot    | functionCall                                  # FuncCallExpr    | fieldAccess                                   # FieldAccessExpr    | literal                                       # LiteralExpr    | '(' expression ')'                            # ParenExpr    ;functionCall    : IDENTIFIER '(' argumentList? ')'    ;argumentList    : expression (',' expression)*    ;fieldAccess    : IDENTIFIER ('.' IDENTIFIER)*    ;literal    : STRING    | NUMBER    | BOOLEAN    | jsonObject    ;jsonObject    : '{' (jsonPair (',' jsonPair)*)? '}'    ;jsonPair    : STRING ':' expression    ;IF: 'if';ELSE: 'else';RETURN: 'return';AND: '&amp;&amp;';OR: '||';NOT: '!';BOOLEAN: 'true' | 'false';NUMBER: '-'? [0-9]+ ('.' [0-9]+)?;STRING: '\"' (~[\"\\\\] | '\\\\' .)* '\"';IDENTIFIER: [a-zA-Z_][a-zA-Z0-9_]*;WS: [ \\t\\r\\n]+ -&gt; skip;COMMENT: '\/\/' ~[\\r\\n]* -&gt; skip;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p> \u041a\u0430\u043a \u0432\u0438\u0434\u0438\u0442\u0435 \u043f\u0440\u0430\u0432\u0438\u043b \u043d\u0435 \u0442\u0430\u043a \u043c\u043d\u043e\u0433\u043e. \u041d\u0435\u0442 \u0446\u0438\u043a\u043b\u043e\u0432, \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0438 \u043c\u043d\u043e\u0433\u043e \u0447\u0435\u0433\u043e. \u041d\u0430 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043c\u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0438 \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0443 \u0434\u043b\u044f \u044f\u0437\u044b\u043a\u0430. \u041f\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c javascript. \u0418 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442 \u0438 \u043b\u0435\u0433\u043a\u043e \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u0442\u044c \u043a \u0441\u0442\u0430\u0431\u0443. \u0418 \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043b\u043e\u0441\u044c.  <\/p>\n<p>\u0423 wiremock \u0435\u0441\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d \u0438\u043b\u0438 \u043f\u0440\u0438\u043c\u0435\u0440 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435: <a href=\"https:\/\/github.com\/wiremock\/wiremock-extension-template\" rel=\"noopener noreferrer nofollow\">wiremock-extension-template<\/a><\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0443 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043d\u0443\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438.<\/p>\n<p>\u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u0432 gradle<\/p>\n<pre><code>    antlr 'org.antlr:antlr4:4.13.2'    implementation 'org.antlr:antlr4-runtime:4.13.2'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<ul>\n<li>\n<p><code><strong>antlr 'org.antlr:antlr4:4.13.2'<\/strong><\/code>: <strong>\u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430.<\/strong> \u041f\u043b\u0430\u0433\u0438\u043d <code>antlr<\/code> \u0432 Gradle \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u044d\u0442\u0443 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c ANTLR Tool \u0438 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c Java-\u043a\u043b\u0430\u0441\u0441\u044b \u0438\u0437 <code>.g4<\/code> \u0444\u0430\u0439\u043b\u043e\u0432 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u042d\u0442\u0438 \u043a\u043b\u0430\u0441\u0441\u044b \u043f\u043e\u044f\u0432\u044f\u0442\u0441\u044f \u0432 \u043f\u0430\u043f\u043a\u0435 <code>build\/generated-src\/...<\/code> \u0438 \u0431\u0443\u0434\u0443\u0442 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c.<\/p>\n<\/li>\n<li>\n<p><code><strong>implementation 'org.antlr:antlr4-runtime:4.13.2'<\/strong><\/code>: <strong>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f.<\/strong>  \u0427\u0442\u043e\u0431\u044b \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u043c\u043e\u0433\u043b\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435 (\u043a\u043e\u0433\u0434\u0430 WireMock \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441): \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0442\u043e\u043a\u0435\u043d\u044b, \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0434\u0435\u0440\u0435\u0432\u044c\u044f \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u0438 \u043e\u0431\u0445\u043e\u0434\u0438\u0442\u044c \u0438\u0445<\/p>\n<\/li>\n<\/ul>\n<p>B \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043d\u0443\u0436\u043d\u043e \u0435\u0449\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0430\u043f\u043a\u0443 <code>src\/main\/antlr<\/code> (\u0435\u0451 \u043d\u0435\u0442 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e) \u0438 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435 \u0442\u0443\u0434\u0430 \u043d\u0430\u0448 <code>WiremockJs.g4<\/code><\/p>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u0432 \u0445\u043e\u0434\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0430 \u044f\u0437\u044b\u043a\u0430 \u043f\u0440\u0435\u0442\u0435\u0440\u043f\u0435\u043b\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0438 \u0441\u0442\u0430\u043b\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043b\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>grammar WiremockJs;script    : statement+ EOF    ;statement    : ifStatement    | returnStatement    | varDeclaration    | forEachStatement    ;forEachStatement    : FOR '(' VAR IDENTIFIER OF expression ')' '{' statement* '}'    ;varDeclaration    : VAR IDENTIFIER '=' expression ';'    ;ifStatement    : IF '(' expression ')' '{' thenStmt+=statement+ '}' (ELSE '{' elseStmt+=statement+ '}')?    ;returnStatement    : RETURN expression ';'    ;expression    : expression op=('*'|'\/'|'%') expression        # MulDiv    | expression op=('+'|'-') expression            # AddSub    | expression op=('&gt;'|'&gt;='|'&lt;'|'&lt;=') expression  # Compare    | expression op=('=='|'!=') expression          # Equality    | expression AND expression                     # LogicalAnd    | expression OR expression                      # LogicalOr    | NOT expression                                # LogicalNot    | functionCall                                  # FuncCallExpr    | fieldAccess                                   # FieldAccessExpr    | IDENTIFIER                                     # VarRefExpr    | literal                                       # LiteralExpr    | '(' expression ')'                            # ParenExpr    ;functionCall    : IDENTIFIER '(' argumentList? ')'    ;argumentList    : expression (',' expression)*    ;fieldAccess    : IDENTIFIER ('.' IDENTIFIER)+    ;literal    : STRING    | NUMBER    | BOOLEAN    | NULL    | jsonObject    ;jsonObject    : '{' (jsonPair (',' jsonPair)*)? '}'    ;jsonPair    : STRING ':' expression    ;IF: 'if';ELSE: 'else';RETURN: 'return';VAR: 'var';NULL: 'null';AND: '&amp;&amp;';OR: '||';NOT: '!';FOR: 'for';OF: 'of';BOOLEAN: 'true' | 'false';NUMBER: '-'? [0-9]+ ('.' [0-9]+)?;STRING: '\"' (~[\"\\\\] | '\\\\' .)* '\"';IDENTIFIER: [a-zA-Z_][a-zA-Z0-9_]*;WS: [ \\t\\r\\n]+ -&gt; skip;COMMENT: '\/\/' ~[\\r\\n]* -&gt; skip;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p><a class=\"anchor\" name=\"sravnenie-grammatik-bylo-i-stalo\" id=\"sravnenie-grammatik-bylo-i-stalo\"><\/a><\/p>\n<h4>\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a \u0431\u044b\u043b\u043e \u0438 \u0441\u0442\u0430\u043b\u043e<\/h4>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0411\u044b\u043b\u043e (v1)<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0421\u0442\u0430\u043b\u043e (v2)<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0427\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u043e\u0441\u044c<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0441\u043b\u043e\u0432\u0430<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">4 (<code>if<\/code>, <code>else<\/code>, <code>return<\/code>, <code>true\/false<\/code>)<\/p>\n<\/td>\n<td>\n<p align=\"left\">8 (+<code>var<\/code>, <code>null<\/code>, <code>for<\/code>, <code>of<\/code>)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u0446\u0438\u043a\u043b\u044b \u0438 null<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u0422\u0438\u043f\u044b statement<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">2 (<code>if<\/code>, <code>return<\/code>)<\/p>\n<\/td>\n<td>\n<p align=\"left\">4 (+<code>varDeclaration<\/code>, <code>forEachStatement<\/code>)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0438 \u0446\u0438\u043a\u043b\u044b<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u0422\u0438\u043f\u044b \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">10<\/p>\n<\/td>\n<td>\n<p align=\"left\">11 (+<code>VarRefExpr<\/code>)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041b\u0438\u0442\u0435\u0440\u0430\u043b\u044b<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">4 (<code>string<\/code>, <code>number<\/code>, <code>boolean<\/code>, <code>json<\/code>)<\/p>\n<\/td>\n<td>\n<p align=\"left\">5 (+<code>null<\/code>)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d null-\u043b\u0438\u0442\u0435\u0440\u0430\u043b<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">16<\/p>\n<\/td>\n<td>\n<p align=\"left\">19<\/p>\n<\/td>\n<td>\n<p align=\"left\">+3 \u043d\u043e\u0432\u044b\u0445 \u043f\u0440\u0430\u0432\u0438\u043b\u0430<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u0431\u044b\u043b\u0430 <strong>\u043c\u0438\u043d\u0438\u043c\u0430\u043b\u0438\u0441\u0442\u0438\u0447\u043d\u043e\u0439<\/strong> \u2014 \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0442. \u042d\u0442\u043e\u0433\u043e \u0445\u0432\u0430\u0442\u0430\u043b\u043e \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432, \u043d\u043e \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u043e\u0432 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u044c\u0448\u0435.<\/p>\n<p><a class=\"anchor\" name=\"grammaticheskie-pravila\" id=\"grammaticheskie-pravila\"><\/a><\/p>\n<h4>\u0413\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430<\/h4>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041f\u0440\u0430\u0432\u0438\u043b\u043e \/ \u0422\u043e\u043a\u0435\u043d<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0440\u043e\u0434\u0443\u043a\u0446\u0438\u044f (\u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441)<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u0435<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>script<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>statement+ EOF<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043a\u0440\u0438\u043f\u0442 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043e\u0434\u043d\u043e\u0439 \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439, \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0438\u0434\u0451\u0442 \u043a\u043e\u043d\u0435\u0446 \u0444\u0430\u0439\u043b\u0430.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>statement<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>ifStatement<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>returnStatement<\/code> **<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code><strong>varDeclaration<\/strong><\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code><strong>VAR IDENTIFIER '=' expression ';'<\/strong><\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u041e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0441 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c. \u041e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u2014 \u0432\u0435\u0441\u044c \u0441\u043a\u0440\u0438\u043f\u0442.<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code><strong>forEachStatement<\/strong><\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code><strong>FOR '(' VAR IDENTIFIER OF expression ')' '{' statement\\* '}'<\/strong><\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0426\u0438\u043a\u043b \u043f\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u0430 (\u0438\u043b\u0438 \u0438\u0442\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430). \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0446\u0438\u043a\u043b\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430.<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>ifStatement<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>IF '(' expression ')' '{' thenStmt+=statement+ '}'<\/code> <code>(ELSE '{' elseStmt+=statement+ '}')?<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0423\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u0441 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u0431\u043b\u043e\u043a\u043e\u043c <code>then<\/code> \u0438 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c <code>else<\/code>. \u0412\u043d\u0443\u0442\u0440\u0438 \u0431\u043b\u043e\u043a\u043e\u0432 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>returnStatement<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>RETURN expression ';'<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u0430.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>expression<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">`expression op=(\u2018*\u2019<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2018\/\u2019<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>functionCall<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>IDENTIFIER '(' argumentList? ')'<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u0441 \u043d\u0443\u043b\u0451\u043c \u0438\u043b\u0438 \u0431\u043e\u043b\u0435\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435\u043c (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>query()<\/code>, <code>jsonField()<\/code>).<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>argumentList<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>expression (',' expression)*<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043f\u0438\u0441\u043e\u043a \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0440\u0430\u0437\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0445 \u0437\u0430\u043f\u044f\u0442\u044b\u043c\u0438.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>fieldAccess<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code><strong>IDENTIFIER ('.' IDENTIFIER)+<\/strong><\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0414\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0447\u0435\u0440\u0435\u0437 \u0442\u043e\u0447\u0435\u0447\u043d\u0443\u044e \u043d\u043e\u0442\u0430\u0446\u0438\u044e. <strong>\u0412 v2 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u043d\u043e \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043a \u043f\u043e\u043b\u044e (\u0442.\u0435. <\/strong><code><strong>user.name<\/strong><\/code><strong> \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e, \u0430 \u043f\u0440\u043e\u0441\u0442\u043e <\/strong><code><strong>user<\/strong><\/code><strong> \u2014 \u044d\u0442\u043e \u0443\u0436\u0435 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e).<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>literal<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>STRING<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>NUMBER<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>jsonObject<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>'{' (jsonPair (',' jsonPair)*)? '}'<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">JSON-\u043e\u0431\u044a\u0435\u043a\u0442 \u0432 \u0444\u0438\u0433\u0443\u0440\u043d\u044b\u0445 \u0441\u043a\u043e\u0431\u043a\u0430\u0445, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u043d\u043e\u043b\u044c \u0438\u043b\u0438 \u0431\u043e\u043b\u0435\u0435 \u043f\u0430\u0440 \u00ab\u043a\u043b\u044e\u0447: \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u00bb.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>jsonPair<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>STRING ':' expression<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0430\u0440\u0430 \u043a\u043b\u044e\u0447-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 JSON-\u043e\u0431\u044a\u0435\u043a\u0442\u0435: \u043a\u043b\u044e\u0447 \u2014 \u0441\u0442\u0440\u043e\u043a\u0430, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u2014 \u043b\u044e\u0431\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><a class=\"anchor\" name=\"leksicheskie-tokeny\" id=\"leksicheskie-tokeny\"><\/a><\/p>\n<h4>\u041b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0442\u043e\u043a\u0435\u043d\u044b<\/h4>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0422\u043e\u043a\u0435\u043d<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0420\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u0435\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u0435<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>IF<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>'if'<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e \u0443\u0441\u043b\u043e\u0432\u043d\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>ELSE<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>'else'<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e \u0434\u043b\u044f \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u0432\u0435\u0442\u043a\u0438.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>RETURN<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>'return'<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code><strong>VAR<\/strong><\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code><strong>'var'<\/strong><\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u041a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e \u0434\u043b\u044f \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439.<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code><strong>FOR<\/strong><\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code><strong>'for'<\/strong><\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u041a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e \u0446\u0438\u043a\u043b\u0430.<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code><strong>OF<\/strong><\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code><strong>'of'<\/strong><\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u041a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e \u0434\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u0438\u0442\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432 \u0446\u0438\u043a\u043b\u0435.<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code><strong>NULL<\/strong><\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code><strong>'null'<\/strong><\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u041b\u0438\u0442\u0435\u0440\u0430\u043b \u043d\u0443\u043b\u0435\u0432\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>AND<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>'&amp;&amp;'<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0418.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>OR<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">`\u2019<\/p>\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>NOT<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>'!'<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043e\u0442\u0440\u0438\u0446\u0430\u043d\u0438\u0435.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>BOOLEAN<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>'true'<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>'false'<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>NUMBER<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>'-'? [0-9]+ ('.' [0-9]+)?<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0427\u0438\u0441\u043b\u043e\u0432\u044b\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044b (\u0446\u0435\u043b\u044b\u0435 \u0438\u043b\u0438 \u0434\u0440\u043e\u0431\u043d\u044b\u0435, \u0441 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u0437\u043d\u0430\u043a\u043e\u043c \u043c\u0438\u043d\u0443\u0441).<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>STRING<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">`\u2018&#187;\u2019 (~[&#171;\\]<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2018\\\u2019 .)* \u2018&#187;\u2019`<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>IDENTIFIER<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>[a-zA-Z_][a-zA-Z0-9_]*<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0418\u043c\u0435\u043d\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0438 \u043f\u043e\u043b\u0435\u0439 (\u0431\u0443\u043a\u0432\u044b, \u0446\u0438\u0444\u0440\u044b, \u043f\u043e\u0434\u0447\u0451\u0440\u043a\u0438\u0432\u0430\u043d\u0438\u0435, \u043d\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442\u0441\u044f \u0441 \u0446\u0438\u0444\u0440\u044b).<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>WS<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>[ \\t\\r\\n]+ -&gt; skip<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0440\u043e\u0431\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u044e\u0442\u0441\u044f.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>COMMENT<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>'\/\/' ~[\\r\\n]* -&gt; skip<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041e\u0434\u043d\u043e\u0441\u0442\u0440\u043e\u0447\u043d\u044b\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 (\u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442\u0441\u044f \u0441 <code>\/\/<\/code>) \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u044e\u0442\u0441\u044f.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><a class=\"anchor\" name=\"visitor-kak-derevo-razbora-prevraschaetsya-v-rezultat\" id=\"visitor-kak-derevo-razbora-prevraschaetsya-v-rezultat\"><\/a><\/p>\n<h3>Visitor: \u043a\u0430\u043a \u0434\u0435\u0440\u0435\u0432\u043e \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/h3>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u043f\u043e\u0433\u0440\u0443\u0437\u0438\u0442\u044c\u0441\u044f \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e, \u0441\u0442\u043e\u0438\u0442 \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0430\u0440\u0443 \u0441\u043b\u043e\u0432 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a ANTLR \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0431\u0445\u043e\u0434\u0438\u0442\u044c \u0434\u0435\u0440\u0435\u0432\u043e \u0440\u0430\u0437\u0431\u043e\u0440\u0430. \u0412 ANTLR \u0435\u0441\u0442\u044c \u0434\u0432\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e: <strong>Listener<\/strong> \u0438 <strong>Visitor<\/strong>.<\/p>\n<p>Listener \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u043e \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0443 \u00abpush\u00bb \u2014 ANTLR \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u0431\u0445\u043e\u0434\u0438\u0442 \u0434\u0435\u0440\u0435\u0432\u043e \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0432\u0430\u0448\u0438 \u043c\u0435\u0442\u043e\u0434\u044b \u043f\u0440\u0438 \u0432\u0445\u043e\u0434\u0435 \u0432 \u0443\u0437\u0435\u043b \u0438 \u0432\u044b\u0445\u043e\u0434\u0435 \u0438\u0437 \u043d\u0435\u0433\u043e. \u041d\u043e \u043c\u0435\u0442\u043e\u0434\u044b Listener \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0430\u043c \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0431\u044b \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0432 \u0441\u0442\u0435\u043a\u0435 \u0438\u043b\u0438 \u043f\u043e\u043b\u044f\u0445 \u043a\u043b\u0430\u0441\u0441\u0430<\/p>\n<p>\u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0443\u0436\u043d\u043e <strong>\u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c<\/strong> \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0443\u0437\u043b\u0430 \u0438 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0430\u0432\u0435\u0440\u0445. \u042d\u0442\u043e \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0434\u043b\u044f <strong>Visitor<\/strong>. \u041e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u043e \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0443 \u00abpull\u00bb \u2014 \u0432\u044b \u0441\u0430\u043c\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0435 \u043e\u0431\u0445\u043e\u0434\u043e\u043c, \u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 <code>visit<\/code> \u043c\u043e\u0436\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 (\u0447\u0438\u0441\u043b\u043e, \u0441\u0442\u0440\u043e\u043a\u0443, \u0431\u0443\u043b\u0435\u0432\u043e, JSON-\u043e\u0431\u044a\u0435\u043a\u0442). \u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043b\u043e\u0436\u0438\u0442\u0441\u044f \u043d\u0430 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0446\u0438\u044e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439.<\/p>\n<p>ANTLR \u043f\u043e \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u0440\u0441\u0435\u0440, \u043d\u043e \u0438 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 <code>WiremockJsBaseVisitor&lt;T&gt;<\/code> \u0441 \u0437\u0430\u0433\u043e\u0442\u043e\u0432\u043a\u043e\u0439 \u043c\u0435\u0442\u043e\u0434\u0430 \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u2014 <code>visitIfStatement<\/code>, <code>visitReturnStatement<\/code>, <code>visitCompare<\/code>, <code>visitMulDiv<\/code>, <code>visitEquality<\/code>, <code>visitFuncCallExpr<\/code>, <code>visitLiteral<\/code>, <code>visitFieldAccessExpr<\/code> \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u041a\u043b\u0430\u0441\u0441 <code>WiremockJsInterpreter<\/code> \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u044d\u0442\u043e\u0442 Visitor \u0438 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043d\u0443\u0436\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u2014 \u043f\u043e \u0441\u0443\u0442\u0438, \u044d\u0442\u043e \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d \u201c\u043e\u0431\u043e\u0439\u0442\u0438 \u0434\u0435\u0440\u0435\u0432\u043e \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u0438 \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u043c \u0443\u0437\u043b\u0435 \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u201d.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/994\/23e\/fa7\/99423efa72df0660e1bf50f1d80d0949.png\" alt=\"image-20260802152246476\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/994\/23e\/fa7\/99423efa72df0660e1bf50f1d80d0949.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/994\/23e\/fa7\/99423efa72df0660e1bf50f1d80d0949.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802152246476<\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u0443\u0437\u043b\u0430 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f (<code>&gt;<\/code>, <code>&gt;=<\/code>, <code>&lt;<\/code>, <code>&lt;=<\/code>) Visitor \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442 \u043e\u0431\u0435 \u0447\u0430\u0441\u0442\u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e (<code>visit(ctx.expression(0))<\/code>, <code>visit(ctx.expression(1))<\/code>), \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u0438\u0445 \u043a \u0447\u0438\u0441\u043b\u0443 \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u043f\u043e \u0442\u0435\u043a\u0441\u0442\u0443 \u0442\u043e\u043a\u0435\u043d\u0430:<\/p>\n<pre><code class=\"java\">    @Override    public Object visitCompare(WiremockJsParser.CompareContext ctx) {        double left = num(visit(ctx.expression(0)));        double right = num(visit(ctx.expression(1)));        String op = ctx.op.getText();        if (op.equals(\"&gt;\")) return left &gt; right;        if (op.equals(\"&gt;=\")) return left &gt;= right;        if (op.equals(\"&lt;\")) return left &lt; right;        if (op.equals(\"&lt;=\")) return left &lt;= right;         throw new ScriptExecutionException(\"\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f\");     }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u0441\u043f\u0443\u0441\u043a \u043f\u043e AST \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435: \u043a\u0430\u0436\u0434\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 <code>visit(...)<\/code> \u2014 \u044d\u0442\u043e \u0441\u043f\u0443\u0441\u043a \u043d\u0430 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0439 \u0443\u0437\u0435\u043b \u0434\u0435\u0440\u0435\u0432\u0430, \u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u0438\u0437 \u043c\u0435\u0442\u043e\u0434\u0430 \u2014 \u201c\u0432\u0441\u043f\u043b\u044b\u0442\u0438\u0435\u201d \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u043d\u0430\u0432\u0435\u0440\u0445, \u043f\u043e\u043a\u0430 \u0432\u0435\u0441\u044c \u0441\u043a\u0440\u0438\u043f\u0442 \u043d\u0435 \u0441\u0432\u0435\u0440\u043d\u0451\u0442\u0441\u044f \u0432 \u043e\u0434\u0438\u043d <code>Map&lt;String, Object&gt;<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 <code>visitReturnStatement<\/code> \u043e\u0442\u0434\u0430\u0451\u0442 \u043a\u0430\u043a \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u0414\u043e\u0441\u0442\u0443\u043f \u043a \u043f\u043e\u043b\u044f\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0447\u0435\u0440\u0435\u0437 \u0442\u043e\u0447\u043a\u0443 (<code>order.amount<\/code>) \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u2014 <code>visitFieldAccessExpr<\/code> \u0431\u0435\u0440\u0451\u0442 \u043f\u0435\u0440\u0432\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0438\u0437 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u044b\u0445 <code>var<\/code>-\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0432 scope, \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u201c\u0441\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f\u201d \u043f\u043e <code>Map<\/code>, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044f <code>null<\/code> \u043f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u043c \u043f\u043e\u043b\u0435 \u0438 \u0431\u0440\u043e\u0441\u0430\u044f <code>ScriptExecutionException<\/code>, \u0435\u0441\u043b\u0438 \u0431\u0430\u0437\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u2014 \u043d\u0435 \u043e\u0431\u044a\u0435\u043a\u0442<\/p>\n<p><a class=\"anchor\" name=\"kak-wiremock-uznaet-pro-rasshirenie\" id=\"kak-wiremock-uznaet-pro-rasshirenie\"><\/a><\/p>\n<h3>\u041a\u0430\u043a WireMock \u0443\u0437\u043d\u0430\u0451\u0442 \u043f\u0440\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435?<\/h3>\n<p>WireMock \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0439 \u043a\u043e\u0434 \u0434\u0432\u0443\u043c\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438: \u043b\u0438\u0431\u043e \u043a\u043b\u0430\u0441\u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>Extension<\/code> \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e, \u043b\u0438\u0431\u043e \u0447\u0435\u0440\u0435\u0437 <code>ExtensionFactory<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 WireMock \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u0447\u0435\u0440\u0435\u0437 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c <code>META-INF\/services<\/code> (Java <code>ServiceLoader<\/code>).<\/p>\n<p>\u0415\u0441\u0442\u044c \u043d\u044e\u0430\u043d\u0441, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0442\u043e\u0438\u0442 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435: \u0432 WireMock 3.13.1 \u0444\u043b\u0430\u0433 <code>--extensions<\/code> \u0432 CLI \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u043a\u043b\u0430\u0441\u0441, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0439 \u0438\u043c\u0435\u043d\u043d\u043e <code>Extension<\/code>, \u0430 \u043d\u0435 \u0444\u0430\u0431\u0440\u0438\u043a\u0443. \u041f\u043e\u043f\u044b\u0442\u043a\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0442\u0443\u0434\u0430 <code>ExtensionFactory<\/code> \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u0442 \u043a <code>ClassCastException: cannot be cast to class Extension<\/code>. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u044e \u0441\u0440\u0430\u0437\u0443 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b:<\/p>\n<p><code>--extensions=ru.mcs.wiremockjs.ScriptTransformer,ru.mcs.wiremockjs.admin.ScriptAdminApi<\/code>.<\/p>\n<ul>\n<li>\n<p><code>ScriptTransformer<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 <code>ResponseDefinitionTransformerV2<\/code> \u2014 \u044d\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0434\u0432\u0438\u0436\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0441\u043a\u0440\u0438\u043f\u0442\u044b.<\/p>\n<\/li>\n<li>\n<p><code>ScriptAdminApi<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 <code>AdminApiExtension<\/code> \u2014 \u043e\u043d \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 REST-\u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u044b \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043a\u0440\u0438\u043f\u0442\u0430\u043c\u0438 (\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430, \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435, \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435) \u043f\u0440\u044f\u043c\u043e \u0447\u0435\u0440\u0435\u0437 API WireMock.<\/p>\n<\/li>\n<\/ul>\n<p><a class=\"anchor\" name=\"tochka-vhoda-transform\" id=\"tochka-vhoda-transform\"><\/a><\/p>\n<h4>\u0422\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430: transform()<\/h4>\n<p>\u0422\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430 \u0434\u043b\u044f \u043b\u043e\u0433\u0438\u043a\u0438 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 \u2014 \u043c\u0435\u0442\u043e\u0434 <code>transform(ServeEvent)<\/code> \u0432 <code>ScriptTransformer<\/code>. \u041d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441, \u043f\u043e\u043f\u0430\u0432\u0448\u0438\u0439 \u043f\u043e\u0434 \u0441\u0442\u0430\u0431 \u0441 <code>transformers: [\"wiremock-js\"]<\/code>, WireMock \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u044f <code>ServeEvent<\/code>, \u0438\u0437 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442\u0441\u044f <code>scriptId<\/code>, \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 <code>ScriptDefinition<\/code> \u0432 <code>ScriptStore<\/code>, \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440:<\/p>\n<details class=\"spoiler\">\n<summary>ScriptTransformer.class<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">public class ScriptTransformer implements ResponseDefinitionTransformerV2 {    private static final long EXECUTION_TIMEOUT_MS = 100;@Override    public ResponseDefinition transform(ServeEvent serveEvent) {        Parameters parameters = serveEvent.getTransformerParameters();        String scriptId = parameters.getString(\"scriptId\");        if (scriptId == null || scriptId.isBlank()) {            throw new ScriptExecutionException(\"\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 scriptId \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d \u0432 transformerParameters\");        }        ScriptDefinition definition = scriptStore.findById(scriptId).orElseThrow(() -&gt; new ScriptExecutionException(\"\u0421\u043a\u0440\u0438\u043f\u0442 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d: \" + scriptId));        ScriptGuard.validate(definition.getSourceCode());        RequestFacade facade = new RequestFacade(serveEvent.getRequest());        WiremockJsInterpreter interpreter = new WiremockJsInterpreter(facade);        Map&lt;String, Object&gt; result = executeWithTimeout(interpreter, definition.getSourceCode());        return buildResponse(serveEvent.getResponseDefinition(), result);    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p><a class=\"anchor\" name=\"zaschita-ot-zavisaniy-taymaut-vypolneniya\" id=\"zaschita-ot-zavisaniy-taymaut-vypolneniya\"><\/a><\/p>\n<h4>\u0417\u0430\u0449\u0438\u0442\u0430 \u043e\u0442 \u0437\u0430\u0432\u0438\u0441\u0430\u043d\u0438\u0439: \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f<\/h4>\n<p>\u0414\u043b\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u044f \u043e\u0431\u0435\u0440\u043d\u0443\u043b \u0432 <code>CompletableFuture<\/code> \u0441 \u044f\u0432\u043d\u044b\u043c \u0432\u044b\u0437\u043e\u0432\u043e\u043c <code>future.get(100, TimeUnit.MILLISECONDS)<\/code>. \u041f\u0440\u0438 \u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u0438 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>future.cancel(true)<\/code>, \u0447\u0442\u043e \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0439\u0441\u044f \u043f\u043e\u0442\u043e\u043a, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>ScriptExecutionException<\/code>. \u0422\u0430\u0439\u043c\u0430\u0443\u0442 \u0432 100 \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434 \u0434\u0430\u0451\u0442 \u0440\u0435\u0430\u043b\u044c\u043d\u0443\u044e \u0437\u0430\u0449\u0438\u0442\u0443 \u043e\u0442 \u0437\u0430\u0432\u0438\u0441\u0448\u0438\u0445 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 JVM-\u043f\u043e\u0442\u043e\u043a\u0430, \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044f \u043e\u0434\u043d\u043e\u043c\u0443 \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u043c\u0443 \u0441\u043a\u0440\u0438\u043f\u0442\u0443 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0434\u0440\u0443\u0433\u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432.<\/p>\n<details class=\"spoiler\">\n<summary>\u043c\u0435\u0442\u043e\u0434 executeWithTimeout<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">    private Map&lt;String, Object&gt; executeWithTimeout(WiremockJsInterpreter interpreter, String source) {        CompletableFuture&lt;Map&lt;String, Object&gt;&gt; future = CompletableFuture.supplyAsync(                () -&gt; interpreter.execute(source));        try {            return future.get(EXECUTION_TIMEOUT_MS, TimeUnit.MILLISECONDS);        } catch (TimeoutException e) {            future.cancel(true);            throw new ScriptExecutionException(                    \"\u041f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u043a\u0440\u0438\u043f\u0442\u0430 (\" + EXECUTION_TIMEOUT_MS + \" \u043c\u0441)\");        } catch (ExecutionException e) {            Throwable cause = e.getCause();            if (cause instanceof ScriptParseException || cause instanceof ScriptExecutionException) {                throw (RuntimeException) cause;            }            throw new ScriptExecutionException(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u043a\u0440\u0438\u043f\u0442\u0430: \" + cause.getMessage(), cause);        } catch (InterruptedException e) {            Thread.currentThread().interrupt();            throw new ScriptExecutionException(\"\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u043f\u0440\u0435\u0440\u0432\u0430\u043d\u043e\");        }    }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p><a class=\"anchor\" name=\"zachem-nuzhen-requestfacade\" id=\"zachem-nuzhen-requestfacade\"><\/a><\/p>\n<h3>\u0417\u0430\u0447\u0435\u043c \u043d\u0443\u0436\u0435\u043d RequestFacade?<\/h3>\n<p>\u0418\u0434\u0435\u044f \u0444\u0430\u0441\u0430\u0434\u0430 \u043f\u0440\u043e\u0441\u0442\u0430\u044f, \u043d\u043e \u0432\u0430\u0436\u043d\u0430\u044f: \u0441\u043a\u0440\u0438\u043f\u0442 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0432\u0438\u0434\u0438\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 <code>Request<\/code> \u043e\u0442 WireMock \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u2014 \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u0442\u043e\u0434\u044b <code>RequestFacade<\/code>, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0435 \u0447\u0435\u0440\u0435\u0437 whitelist-\u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0430. \u0418\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u044d\u0442\u043e\u043c\u0443 <code>visitFieldAccessExpr<\/code> \u0436\u0451\u0441\u0442\u043a\u043e \u0431\u0440\u043e\u0441\u0430\u0435\u0442 <code>ScriptExecutionException<\/code>, \u0435\u0441\u043b\u0438 \u0441\u043a\u0440\u0438\u043f\u0442 \u043f\u043e\u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c <code>request.method<\/code> \u2014 \u0444\u0430\u0441\u0430\u0434 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435 \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0430\u0440\u0443\u0436\u0443 \u043d\u0438\u0447\u0435\u0433\u043e, \u043a\u0440\u043e\u043c\u0435 \u0441\u0432\u043e\u0438\u0445 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0445 \u0447\u0435\u0440\u0435\u0437 <code>query()<\/code>, <code>header()<\/code>, <code>body()<\/code> \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435.<\/p>\n<p>\u0424\u0430\u0441\u0430\u0434\u0430 \u0438\u043c\u0435\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043d\u0430 \u0431\u0430\u0437\u0435 <code>Request<\/code> \u0438\u0437 WireMock API:<\/p>\n<details class=\"spoiler\">\n<summary>RequestFacade.class<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">public class RequestFacade {    private static final Map&lt;String, JsonPath&gt; PATH_CACHE = new ConcurrentHashMap&lt;&gt;();    private final Request request;    private DocumentContext documentContext;    private boolean documentContextInitialized = false;    public RequestFacade(Request request) {        this.request = request;    }    public Object jsonField(String path) {        DocumentContext context = getOrParseDocumentContext();        if (context == null) {            return null;        }        JsonPath compiledPath = PATH_CACHE.computeIfAbsent(path, JsonPath::compile);        try {            return context.read(compiledPath);        } catch (PathNotFoundException e) {            return null;        } catch (Exception e) {            throw new ScriptExecutionException(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0447\u0442\u0435\u043d\u0438\u0438 JSONPath \\\"\" + path + \"\\\": \" + e.getMessage());        }    }    private DocumentContext getOrParseDocumentContext() {        if (!documentContextInitialized) {            documentContextInitialized = true;            try {                documentContext = JsonPath.parse(request.getBodyAsString());            } catch (Exception e) {                documentContext = null;            }        }        return documentContext;    }    public String query(String name) {        QueryParameter param = request.queryParameter(name);        return (param != null &amp;&amp; param.isPresent()) ? param.firstValue() : null;    }    public String header(String name) {        com.github.tomakehurst.wiremock.http.HttpHeader h = request.header(name);        return (h != null &amp;&amp; h.isPresent()) ? h.firstValue() : null;    }    public String body() {        return request.getBodyAsString();    }    public String method() {        return request.getMethod().getName();    }    public String pathSegment(int index) {        List&lt;String&gt; segments = splitPath(request.getUrl());        return index &gt;= 0 &amp;&amp; index &lt; segments.size() ? segments.get(index) : null;    }    public Map&lt;String, String&gt; allHeaders() {        Map&lt;String, String&gt; result = new HashMap&lt;&gt;();        for (String key : request.getAllHeaderKeys()) {            result.put(key, request.header(key).firstValue());        }        return result;    }    private List&lt;String&gt; splitPath(String url) {        String path = url.split(\"\\\\?\")[0];        return java.util.Arrays.stream(path.split(\"\/\"))                .filter(s -&gt; !s.isBlank())                .collect(java.util.stream.Collectors.toList());    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 <code>splitPath<\/code> \u2014 \u043f\u0443\u0442\u044c \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u0447\u0438\u0449\u0430\u0435\u0442\u0441\u044f \u043e\u0442 query-\u0441\u0442\u0440\u043e\u043a\u0438 (<code>url.split(\"\\\\?\")[0]<\/code>), \u0437\u0430\u0442\u0435\u043c \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b \u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0443\u0435\u0442\u0441\u044f \u043e\u0442 \u043f\u0443\u0441\u0442\u044b\u0445 \u0441\u0442\u0440\u043e\u043a, \u0447\u0442\u043e \u0434\u0430\u0451\u0442 \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u0443\u044e \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u044e: <code>\/api\/customer\/vip<\/code> \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 <code>[\"api\", \"customer\", \"vip\"]<\/code>, \u0430 \u043d\u0435 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u043f\u0443\u0441\u0442\u044b\u043c \u043f\u0435\u0440\u0432\u044b\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c \u0438\u0437-\u0437\u0430 \u0432\u0435\u0434\u0443\u0449\u0435\u0433\u043e \u0441\u043b\u0435\u0448\u0430.<\/p>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0431\u044b\u043b\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0432 WiremockJsInterpreter:<\/p>\n<pre><code class=\"java\">private Object callWhitelistedFunction(String name, List&lt;Object&gt; args) {    switch (name) {        case \"query\": return requestFacade.query(str(args, 0));        case \"header\": return requestFacade.header(str(args, 0));        case \"body\": return requestFacade.body();        case \"method\": return requestFacade.method();        case \"pathSegment\": return requestFacade.pathSegment((int) num(args, 0));        case \"contains\":            return str(args, 0) != null &amp;&amp; str(args, 0).contains(str(args, 1));        default:            throw new ScriptExecutionException(\"\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043d\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0430 \u0438\u043b\u0438 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442: \" + name);    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0424\u0443\u043d\u043a\u0446\u0438\u044f<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0421\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>query(name)<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>query(String) -&gt; String | null<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 query-\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>null<\/code>, \u0435\u0441\u043b\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>header(name)<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>header(String) -&gt; String | null<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>null<\/code>, \u0435\u0441\u043b\u0438 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>body()<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>body() -&gt; String<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0422\u0435\u043b\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043a\u0430\u043a \u0441\u0442\u0440\u043e\u043a\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0411\u0435\u0437 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 JSON, \u0441\u044b\u0440\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>method()<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>method() -&gt; String<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">HTTP-\u043c\u0435\u0442\u043e\u0434<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>\"GET\"<\/code>, <code>\"POST\"<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>pathSegment(index)<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>pathSegment(Number) -&gt; String | null<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u0435\u0433\u043c\u0435\u043d\u0442 \u043f\u0443\u0442\u0438 \u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0443<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>\/api\/customer\/vip<\/code> \u2192 <code>pathSegment(2)<\/code> = <code>\"vip\"<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>contains(str, substr)<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>contains(String, String) -&gt; Boolean<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">true\/false<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 <code>null<\/code> \u043a\u0430\u043a \u043f\u0435\u0440\u0432\u044b\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041d\u043e \u043f\u043e\u0442\u043e\u043c \u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u043b \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u043c\u0435\u0442\u043e\u0434\u044b: random, now, nowPlusDays, uuid, randomInt, matches, fake, sum, count, avg, mapKeys.<\/p>\n<details class=\"spoiler\">\n<summary>\u041c\u0435\u0442\u043e\u0434 callWhitelistedFunction<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">case \"query\": return requestFacade.query(str(args, 0));case \"header\": return requestFacade.header(str(args, 0));case \"body\": return requestFacade.body();case \"method\": return requestFacade.method();case \"pathSegment\": return requestFacade.pathSegment((int) num(args, 0));case \"jsonField\": return requestFacade.jsonField(str(args, 0));case \"contains\": {    String haystack = str(args, 0);    String needle = str(args, 1);    if (haystack == null || needle == null) {        return false;    }    return haystack.contains(needle);}case \"random\": return random.nextDouble();case \"now\": return Instant.now().toString();case \"nowPlusDays\": return Instant.now().plus((long) num(args, 0), ChronoUnit.DAYS).toString();case \"uuid\": return generateUuid();case \"randomInt\": return (double) randomInt((int) num(args, 0), (int) num(args, 1));case \"matches\": {    String input = str(args, 0);    String pattern = str(args, 1);    if (input == null || pattern == null) {        return false;    }    try {        return com.google.re2j.Pattern.matches(pattern, input);    } catch (com.google.re2j.PatternSyntaxException e) {        throw new ScriptExecutionException(\"\u041d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0435 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435: \" + e.getMessage());    }}case \"fake\": {    String pattern = str(args, 0);    if (pattern == null) {        throw new ScriptExecutionException(\"fake(): \u0448\u0430\u0431\u043b\u043e\u043d \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c null\");    }    try {        return faker.expression(pattern);    } catch (Exception e) {        throw new ScriptExecutionException(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435 fake(\\\"\" + pattern + \"\\\"): \" + e.getMessage());    }}case \"sum\": return sumOf(args.get(0));case \"count\": return (double) toList(args.get(0)).size();case \"avg\": {    List&lt;Object&gt; list = toList(args.get(0));    if (list.isEmpty()) {        throw new ScriptExecutionException(\"avg(): \u043f\u0443\u0441\u0442\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432\");    }    return sumOf(args.get(0)) \/ list.size();}case \"mapKeys\": return mapKeys(toList(args.get(0)), toMap(args.get(1)));default:    throw new ScriptExecutionException(\"\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043d\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0430 \u0438\u043b\u0438 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442: \" + name);<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p><a class=\"anchor\" name=\"scriptguard-pervaya-liniya-zaschity-do-antlr\" id=\"scriptguard-pervaya-liniya-zaschity-do-antlr\"><\/a><\/p>\n<h3>ScriptGuard: \u043f\u0435\u0440\u0432\u0430\u044f \u043b\u0438\u043d\u0438\u044f \u0437\u0430\u0449\u0438\u0442\u044b \u0434\u043e ANTLR<\/h3>\n<p>\u0418\u0434\u0435\u044f <code>ScriptGuard<\/code> \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u0441\u0435\u044f\u0442\u044c \u0437\u0430\u0432\u0435\u0434\u043e\u043c\u043e \u043f\u043b\u043e\u0445\u043e\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0434\u0451\u0448\u0435\u0432\u043e \u2014 \u0431\u0435\u0437 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0433\u043e \u043b\u0435\u043a\u0441\u0435\u0440\u0430 \u0438 \u043f\u0430\u0440\u0441\u0435\u0440\u0430 ANTLR, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0430\u043c\u0438 \u043f\u043e \u0441\u0435\u0431\u0435 \u0442\u0440\u0430\u0442\u044f\u0442 \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u043d\u0430 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u0434\u0435\u0440\u0435\u0432\u0430 \u0440\u0430\u0437\u0431\u043e\u0440\u0430. \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0435\u0434\u0438\u043d\u044b\u043c \u043f\u0440\u043e\u0445\u043e\u0434\u043e\u043c \u043f\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0443 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u043f\u043e\u043f\u0443\u0442\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u044f \u0433\u043b\u0443\u0431\u0438\u043d\u0443 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0441\u043a\u043e\u0431\u043e\u043a \u0438 \u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u043a\u0443 \u0441\u0442\u0440\u043e\u043a, \u0441\u043a\u043e\u0431\u043e\u043a \u0438 \u0444\u0438\u0433\u0443\u0440\u043d\u044b\u0445 \u0431\u043b\u043e\u043a\u043e\u0432:<\/p>\n<details class=\"spoiler\">\n<summary>ScriptGuard.class<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">public class ScriptGuard {    private static int maxScriptLength = readMaxScriptLength();    private static final int MAX_NESTING_DEPTH = 5;    private static int readMaxScriptLength() {        return Integer.parseInt(System.getProperty(\"wiremockjs.max.script.length\", \"2000\"));    }    static void reloadMaxScriptLength() {        maxScriptLength = readMaxScriptLength();    }    public static void validate(String source) {        if (source == null || source.isBlank()) {            throw new ScriptTooLargeException(\"\u0421\u043a\u0440\u0438\u043f\u0442 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u043c\");        }        if (source.length() &gt; maxScriptLength) {            throw new ScriptTooLargeException(                    \"\u0421\u043a\u0440\u0438\u043f\u0442 \u043f\u0440\u0435\u0432\u044b\u0448\u0430\u0435\u0442 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0443\u044e \u0434\u043b\u0438\u043d\u0443 \" + maxScriptLength + \" \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432\");        }        int braceDepth = 0;        int maxBraceDepth = 0;        int parenDepth = 0;        boolean inString = false;        char[] chars = source.toCharArray();        for (int i = 0; i &lt; chars.length; i++) {            char c = chars[i];            if (inString) {                if (c == '\\\\') {                    i++; \/\/ \u044d\u043a\u0440\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \u2014 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u0430\u043a \u0435\u0441\u0442\u044c                } else if (c == '\"') {                    inString = false;                }                continue;            }            switch (c) {                case '\"':                    inString = true;                    break;                case '{':                    braceDepth++;                    maxBraceDepth = Math.max(maxBraceDepth, braceDepth);                    break;                case '}':                    braceDepth--;                    if (braceDepth &lt; 0) {                        throw new ScriptParseException(                                \"\u041b\u0438\u0448\u043d\u044f\u044f \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u0441\u043a\u043e\u0431\u043a\u0430 '}' \u0431\u0435\u0437 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0435\u0439\");                    }                    break;                case '(':                    parenDepth++;                    break;                case ')':                    parenDepth--;                    if (parenDepth &lt; 0) {                        throw new ScriptParseException(                                \"\u041b\u0438\u0448\u043d\u044f\u044f \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u0441\u043a\u043e\u0431\u043a\u0430 ')' \u0431\u0435\u0437 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0435\u0439\");                    }                    break;                default:                    break;            }        }        if (inString) {            throw new ScriptParseException(\"\u041d\u0435\u0437\u0430\u043a\u0440\u044b\u0442\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u2014 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u044e\u0449\u0430\u044f \u043a\u0430\u0432\u044b\u0447\u043a\u0430 \\\"\");        }        if (braceDepth != 0) {            throw new ScriptParseException(                    \"\u041d\u0435\u0441\u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0444\u0438\u0433\u0443\u0440\u043d\u044b\u0435 \u0441\u043a\u043e\u0431\u043a\u0438 '{' '}': \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \" + braceDepth + \" \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0438\u0445\");        }        if (parenDepth != 0) {            throw new ScriptParseException(                    \"\u041d\u0435\u0441\u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u0440\u0443\u0433\u043b\u044b\u0435 \u0441\u043a\u043e\u0431\u043a\u0438 '(' ')': \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \" + parenDepth + \" \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0438\u0445\");        }        if (maxBraceDepth &gt; MAX_NESTING_DEPTH) {            throw new ScriptTooLargeException(                    \"\u041f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u0430 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0433\u043b\u0443\u0431\u0438\u043d\u0430 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0431\u043b\u043e\u043a\u043e\u0432: \" + MAX_NESTING_DEPTH);        }    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p><a class=\"anchor\" name=\"dva-momenta-vyzova-na-vhode-i-na-ispolnenii\" id=\"dva-momenta-vyzova-na-vhode-i-na-ispolnenii\"><\/a><\/p>\n<h4>\u0414\u0432\u0430 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0432\u044b\u0437\u043e\u0432\u0430 \u2014 \u043d\u0430 \u0432\u0445\u043e\u0434\u0435 \u0438 \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438<\/h4>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u0442\u044c <code>ScriptGuard.validate()<\/code> \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0432 \u0434\u0432\u0443\u0445 \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u043e\u0447\u043a\u0430\u0445 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u0441\u043a\u0440\u0438\u043f\u0442\u0430, \u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u043e\u0434\u043d\u043e\u0439. \u041f\u0435\u0440\u0432\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u2014 <code>ScriptAdminApi<\/code> \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 <code>POST<\/code>\/<code>PUT<\/code> \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u043a\u0440\u0438\u043f\u0442\u0430: \u0435\u0441\u043b\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u043d\u0435 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0439 HTTP 400 \u0441 \u0442\u0435\u043b\u043e\u043c <code>{\"error\": \"...\"}<\/code>, \u043d\u0435 \u0434\u043e\u0436\u0438\u0434\u0430\u044f\u0441\u044c \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043a \u0441\u0442\u0430\u0431\u0443:<\/p>\n<pre><code class=\"java\">        router.add(RequestMethod.POST, \"\/extensions\/wiremock-js\/scripts\",                (AdminTask) (Admin admin, ServeEvent serveEvent, PathParams pathParams) -&gt; {                    Request request = serveEvent.getRequest();                    ScriptDefinition def = Json.read(request.getBodyAsString(), ScriptDefinition.class);                    try {                        ScriptGuard.validate(def.getSourceCode());                    } catch (ScriptParseException | ScriptTooLargeException e) {                        return errorResponse(e.getMessage(), 400);                    }                    ScriptDefinition saved = scriptStore.save(def);                    return jsonResponse(saved, 201);                });<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u0442\u043e\u0440\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u2014 <code>ScriptTransformer.transformServeEvent()<\/code>, \u0433\u0434\u0435 <code>ScriptGuard.validate()<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u044f\u043c\u043e \u043f\u0435\u0440\u0435\u0434 \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u043c \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0430 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0439 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441. \u042d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u043d\u044b\u043c (\u0441\u043a\u0440\u0438\u043f\u0442 \u0436\u0435 \u0443\u0436\u0435 \u043f\u0440\u043e\u0448\u0451\u043b \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e \u043f\u0440\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0438), \u043d\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u043e\u0431\u0435\u043b: \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 \u2014 JSON-\u0444\u0430\u0439\u043b\u044b \u043d\u0430 \u0434\u0438\u0441\u043a\u0435, \u0438 \u0442\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0444\u0430\u0439\u043b \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0438\u043b\u0438 \u0447\u0435\u0440\u0435\u0437 \u043f\u0440\u044f\u043c\u043e\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435, \u043c\u0438\u043d\u0443\u044f Admin API \u2014 \u0432\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442, \u0447\u0442\u043e \u0434\u0430\u0436\u0435 \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440 \u043d\u0435 \u043f\u043e\u043f\u0430\u0434\u0451\u0442 \u0441\u043a\u0440\u0438\u043f\u0442, \u043d\u0430\u0440\u0443\u0448\u0430\u044e\u0449\u0438\u0439 \u043b\u0438\u043c\u0438\u0442\u044b.<\/p>\n<p><a class=\"anchor\" name=\"administrirovanie-i-operacii-so-skriptami\" id=\"administrirovanie-i-operacii-so-skriptami\"><\/a><\/p>\n<h3>\u0410\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430\u043c\u0438<\/h3>\n<p>\u0414\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043a\u0440\u0438\u043f\u0442\u0430\u043c\u0438 \u0432 <code>wiremock-js-extension<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 <strong>Admin API<\/strong>. \u0412\u0441\u0435 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u044b \u0438\u043c\u0435\u044e\u0442 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043f\u0443\u0442\u044c <code>\/__admin\/extensions\/wiremock-js\/scripts<\/code><\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041c\u0435\u0442\u043e\u0434<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0443\u0442\u044c<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>GET<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>\/scripts<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 (\u043a\u0440\u0430\u0442\u043a\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f, \u0431\u0435\u0437 <code>sourceCode<\/code>)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>GET<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>\/scripts?name=X<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043e\u0438\u0441\u043a \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 \u043f\u043e \u043f\u043e\u0434\u0441\u0442\u0440\u043e\u043a\u0435 \u0432 \u0438\u043c\u0435\u043d\u0438 (\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u043e\u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0439)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>GET<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>\/scripts\/{id}<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u043e\u043b\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u0435, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0435\u0433\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>POST<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>\/scripts<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0441\u043a\u0440\u0438\u043f\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>PUT<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>\/scripts\/{id}<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0441\u043a\u0440\u0438\u043f\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>DELETE<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>\/scripts\/{id}<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0415\u0441\u043b\u0438 CRUD \u043c\u0435\u0442\u043e\u0434\u044b \u043d\u0435 \u0432\u0437\u044b\u0432\u0430\u044e\u0442 \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432, \u0442\u043e \u0432\u043e\u0442 \u043c\u0435\u0442\u043e\u0434\u044b <code>\/scripts<\/code> \u0438 <code>\/scripts?name=X<\/code> \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u043c\u043d\u0435 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0435.<\/p>\n<p>\u0412 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0435 \u043e\u0434\u0438\u043d \u0441\u043a\u0440\u0438\u043f\u0442 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u0441\u0440\u0430\u0437\u0443 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0441\u0442\u0430\u0431\u0430\u0445. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f:<\/p>\n<ul>\n<li>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 \u0441 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u043e\u0439 \u043a \u0441\u0442\u0430\u0431\u0430\u043c, \u0447\u0442\u043e\u0431\u044b \u0432\u0438\u0434\u0435\u0442\u044c, \u0433\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u0436\u0434\u044b\u0439 \u0441\u043a\u0440\u0438\u043f\u0442, \u0438 \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u044f \u0435\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u043a\u0430\u0442\u044c \u0441\u0442\u0430\u0431\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043b\u0438\u0431\u043e \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0441\u043a\u0440\u0438\u043f\u0442\u044b, \u043b\u0438\u0431\u043e, \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442, \u0441\u043e\u0437\u0434\u0430\u043d\u044b \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0438 \u043d\u0435 \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u044b \u043d\u0438 \u043a \u043e\u0434\u043d\u043e\u043c\u0443 \u0441\u043a\u0440\u0438\u043f\u0442\u0443 \u0438 \u044d\u0442\u043e \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u044f\u0432\u043b\u044f\u0442\u044c \u00ab\u0431\u0435\u0441\u0445\u043e\u0437\u043d\u044b\u0435\u00bb \u043c\u043e\u043a\u0438 \u0438 \u0443\u043f\u0440\u043e\u0449\u0430\u0442\u044c \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u044e \u043d\u0430 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0442\u0435\u043a\u0443\u0449\u0438\u0435 GET-\u043c\u0435\u0442\u043e\u0434\u044b \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0430 \u0432 \u043f\u0435\u0440\u0441\u043f\u0435\u043a\u0442\u0438\u0432\u0435 \u044f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u043e\u0431\u043e\u0433\u0430\u0442\u0438\u0442\u044c API \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u043c\u0438 \u0438 \u0430\u0433\u0440\u0435\u0433\u0438\u0440\u0443\u044e\u0449\u0438\u043c\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438, \u0447\u0442\u043e\u0431\u044b UI \u0441\u0442\u0430\u043b \u043f\u043e-\u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u043c\u0443 \u0443\u0434\u043e\u0431\u043d\u044b\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043c\u043e\u043a\u0430\u043c\u0438.<\/p>\n<p><a class=\"anchor\" name=\"dobavlenie-skriptov\" id=\"dobavlenie-skriptov\"><\/a><\/p>\n<h4>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432:<\/h4>\n<p>\u0427\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c:<\/p>\n<pre><code class=\"bash\">curl -X POST http:\/\/localhost:8888\/__admin\/extensions\/wiremock-js\/scripts \\  -H \"Content-Type: application\/json\" \\  -d '{    \"name\": \"Approve by amount\",    \"description\": \"\u041e\u0434\u043e\u0431\u0440\u044f\u0435\u0442 \u0437\u0430\u044f\u0432\u043a\u0443, \u0435\u0441\u043b\u0438 \u0441\u0443\u043c\u043c\u0430 \u043c\u0435\u043d\u044c\u0448\u0435 1000\",    \"sourceCode\": \"if (query(\\\"amount\\\") &gt; 1000) { return { \\\"approved\\\": false, \\\"reason\\\": \\\"limit exceeded\\\" }; } else { return { \\\"approved\\\": true }; }\"  }'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/da7\/e49\/a3c\/da7e49a3c2041725f80dc43115ec7d51.png\" alt=\"image-20260802154248174\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/da7\/e49\/a3c\/da7e49a3c2041725f80dc43115ec7d51.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/da7\/e49\/a3c\/da7e49a3c2041725f80dc43115ec7d51.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802154248174<\/figcaption><\/div>\n<\/figure>\n<p>\u0410 \u0434\u0430\u043b\u044c\u0448\u0435 \u0443\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0442\u0430\u0431:<\/p>\n<pre><code class=\"bash\">curl -X POST http:\/\/localhost:8888\/__admin\/mappings \\  -H \"Content-Type: application\/json\" \\  -d '{    \"request\": { \"method\": \"GET\", \"urlPath\": \"\/api\/orders\/approve\" },    \"response\": {      \"status\": 200,      \"transformers\": [\"wiremock-js\"],      \"transformerParameters\": { \"scriptId\": \"&lt;ID&gt;\" }    }  }'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/4c9\/b3a\/470\/4c9b3a470c99b28e5f9d9e2b43156270.png\" alt=\"image-20260802154558953\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/4c9\/b3a\/470\/4c9b3a470c99b28e5f9d9e2b43156270.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/4c9\/b3a\/470\/4c9b3a470c99b28e5f9d9e2b43156270.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802154558953<\/figcaption><\/div>\n<\/figure>\n<p>\u0418 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"bash\">curl \"http:\/\/localhost:8888\/api\/orders\/approve?amount=2000\"# {\"approved\":false,\"reason\":\"limit exceeded\"}curl \"http:\/\/localhost:8888\/api\/orders\/approve?amount=500\"# {\"approved\":true}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/cf5\/b27\/26a\/cf5b2726a2af9bb9a8b2fab650a55d01.png\" alt=\"image-20260802154907586\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/cf5\/b27\/26a\/cf5b2726a2af9bb9a8b2fab650a55d01.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/cf5\/b27\/26a\/cf5b2726a2af9bb9a8b2fab650a55d01.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802154907586<\/figcaption><\/div>\n<\/figure>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/c03\/ae8\/0ef\/c03ae80ef47141c6a07c60200dc38a3d.png\" alt=\"image-20260802154919324\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/c03\/ae8\/0ef\/c03ae80ef47141c6a07c60200dc38a3d.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/c03\/ae8\/0ef\/c03ae80ef47141c6a07c60200dc38a3d.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802154919324<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u044f\u0437\u044b\u043a\u0430 \u0443\u043c\u0435\u043b\u0430 \u0447\u0438\u0442\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e query-\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438 \u0438 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b \u043f\u0443\u0442\u0438 \u2014 \u044d\u0442\u043e\u0433\u043e \u0445\u0432\u0430\u0442\u0430\u043b\u043e \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 \u0432\u0440\u043e\u0434\u0435 \u201c\u043e\u0434\u043e\u0431\u0440\u0438\u0442\u044c \u043f\u043e \u0441\u0443\u043c\u043c\u0435\u201d \u0438\u043b\u0438 \u201c\u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0442\u043e\u043a\u0435\u043d\u201d, \u043d\u043e \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u0432 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0447\u0430\u0449\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u043a\u0430\u043a JSON \u0432 \u0442\u0435\u043b\u0435 POST\/PUT-\u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u0430 \u043d\u0435 \u043a\u0430\u043a query-\u0441\u0442\u0440\u043e\u043a\u0430. \u0411\u0435\u0437 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043f\u043e\u043b\u044f\u043c JSON-\u0442\u0435\u043b\u0430 \u0441\u043a\u0440\u0438\u043f\u0442 \u043c\u043e\u0433 \u0440\u0430\u0437\u043b\u0438\u0447\u0430\u0442\u044c \u0437\u0430\u043a\u0430\u0437\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e \u0432\u043d\u0435\u0448\u043d\u0438\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u0430 \u043d\u0435 \u043f\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u043c\u0443 \u0441\u0430\u043c\u043e\u0433\u043e \u0437\u0430\u043a\u0430\u0437\u0430 \u2014 \u0442\u043e \u0435\u0441\u0442\u044c \u043d\u0435\u043b\u044c\u0437\u044f \u0431\u044b\u043b\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0432\u0438\u0434\u0430 \u201c\u0435\u0441\u043b\u0438 <code>order.amount<\/code> \u0431\u043e\u043b\u044c\u0448\u0435 \u043b\u0438\u043c\u0438\u0442\u0430 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442 \u043d\u0435 VIP\u201d \u041d\u043e \u043f\u043e\u0442\u043e\u043c \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0444\u0443\u043d\u043a\u0446\u0438\u0438.<\/p>\n<p><a class=\"anchor\" name=\"funkcii\" id=\"funkcii\"><\/a><\/p>\n<h3>\u0424\u0443\u043d\u043a\u0446\u0438\u0438<\/h3>\n<p><a class=\"anchor\" name=\"jsonfield-path\" id=\"jsonfield-path\"><\/a><\/p>\n<h4>jsonField(path)<\/h4>\n<p><code>jsonField(path)<\/code> \u044d\u0442\u043e \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0439 \u0438 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0434\u043b\u044f \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0434\u0430\u043d\u043d\u044b\u043c \u0438\u0437 \u0442\u0435\u043b\u0430 \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 JSON. \u041e\u043d \u0437\u0430\u043a\u0440\u044b\u043b \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0441 json: \u0435\u0434\u0438\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0430\u0440\u0441\u0438\u0442 \u0442\u0435\u043b\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437 (\u043b\u0435\u043d\u0438\u0432\u043e, \u0441 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0432 <code>parsedBody()<\/code>), \u0430 \u0437\u0430\u0442\u0435\u043c \u043d\u0430\u0432\u0438\u0433\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u043e \u0434\u0435\u0440\u0435\u0432\u0443 <code>JsonNode<\/code> \u0447\u0435\u0440\u0435\u0437 \u043f\u0443\u0442\u044c \u0441 \u0442\u043e\u0447\u043a\u0430\u043c\u0438, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044f \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0438 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u043a\u043b\u044e\u0447\u0438, \u0438 \u0447\u0438\u0441\u043b\u043e\u0432\u044b\u0435 \u0438\u043d\u0434\u0435\u043a\u0441\u044b \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0432 \u043e\u0434\u043d\u043e\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0438 \u2014 <code>jsonField(\"items.0.id\")<\/code>.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0442\u0435\u043b\u043e \u2014 \u043d\u0435 JSON \u0438\u043b\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432\u043e\u0432\u0441\u0435, <code>jsonField<\/code> \u043d\u0435 \u0431\u0440\u043e\u0441\u0430\u0435\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>null<\/code>, \u0438 \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u2014 \u0441\u043a\u0440\u0438\u043f\u0442 \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0430\u0434\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u0440\u0438\u0448\u0451\u043b \u0431\u0435\u0437 \u0442\u0435\u043b\u0430. \u042d\u0442\u043e \u0436\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u0442\u0435\u0441\u0442\u043e\u043c <code>shouldReturnNullForInvalidJsonBody<\/code>, \u0433\u0434\u0435 \u043d\u0430 \u0432\u0445\u043e\u0434 \u043f\u043e\u0434\u0430\u0451\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u0430 <code>\"not a json at all\"<\/code> \u0438 \u043e\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044f \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u044b\u0439 <code>null<\/code>, \u0430 \u043d\u0435 exception.<\/p>\n<pre><code class=\"java\">    @Test    @DisplayName(\"jsonField() \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0439 JSON \u0432 \u0442\u0435\u043b\u0435\")    void shouldReturnNullForInvalidJsonBody() {        when(mockRequest.getBodyAsString()).thenReturn(\"not a json at all\");        String script = \"\"\"            return { \"field\": jsonField(\"anything\") };            \"\"\";        Map&lt;String, Object&gt; result = run(script);        assertEquals(null, result.get(\"field\"));    }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u041f\u0440\u0438\u043c\u0435\u0440\u044b<\/strong>:<\/p>\n<ul>\n<li>\n<p>\u0414\u043b\u044f JSON-\u0437\u0430\u043f\u0440\u043e\u0441\u0430 <code>{\"user\": {\"role\": \"admin\"}}<\/code> \u0432\u044b\u0437\u043e\u0432 <code>jsonField(\"user.role\")<\/code> \u0432\u0435\u0440\u043d\u0451\u0442 \u0441\u0442\u0440\u043e\u043a\u0443 <code>\"admin\"<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0414\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 <code>{\"items\": [{\"id\": 42}]}<\/code> \u0432\u044b\u0437\u043e\u0432 <code>jsonField(\"items[0].id\")<\/code> \u0432\u0435\u0440\u043d\u0451\u0442 \u0447\u0438\u0441\u043b\u043e <code>42<\/code>.<\/p>\n<\/li>\n<\/ul>\n<p><code>jsonField()<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0434\u0432\u0438\u0436\u043e\u043a Jayway JsonPath, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0442\u043e\u0447\u0435\u0447\u043d\u0443\u044e \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044e, \u043d\u043e \u0438 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0432\u044b\u0431\u043e\u0440\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0430, \u0432\u0430\u0439\u043b\u0434\u043a\u0430\u0440\u0434\u044b \u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044e \u043f\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044e.<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0440\u0438\u043c\u0435\u0440<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041a\u043e\u0433\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u043a\u043b\u044e\u0447<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>jsonField(\"user.role\")<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>\"admin\"<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0414\u043e\u0441\u0442\u0443\u043f \u043a \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u043c\u0443 \u043f\u043e\u043b\u044e \u043e\u0431\u044a\u0435\u043a\u0442\u0430<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0418\u043d\u0434\u0435\u043a\u0441 \u043c\u0430\u0441\u0441\u0438\u0432\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>jsonField(\"items[0].id\")<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>42<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041e\u0434\u0438\u043d \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u043f\u043e \u043f\u043e\u0437\u0438\u0446\u0438\u0438<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0412\u0430\u0439\u043b\u0434\u043a\u0430\u0440\u0434 (\u0432\u0441\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b)<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>jsonField(\"items[*].price\")<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>[100, 200, 300]<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043e\u0431\u0440\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044f \u0441\u043e \u0432\u0441\u0435\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0430, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u0435\u0440\u0435\u0434 <code>sum()<\/code> \u0438\u043b\u0438 <code>avg()<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0424\u0438\u043b\u044c\u0442\u0440 \u043f\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044e<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>jsonField(\"items[?(@.status=='active')].id\")<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>[1, 3]<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043c\u0430\u0441\u0441\u0438\u0432\u0430, \u0447\u0442\u043e \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0442 \u0443\u0441\u043b\u043e\u0432\u0438\u044e<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0424\u0438\u043b\u044c\u0442\u0440 \u0431\u0435\u0437 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0439<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>jsonField(\"items[?(@.status=='active')].id\")<\/code> \u043d\u0430 \u043f\u0443\u0441\u0442\u043e\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>[]<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043d\u0435 \u0431\u0440\u043e\u0441\u0430\u0435\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u2014 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u0443\u0441\u0442\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a, \u0430 \u043d\u0435 null<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041d\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043f\u0443\u0442\u044c<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>jsonField(\"user.address.city\")<\/code> \u043f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u043f\u043e\u043b\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>null<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043a\u0440\u0438\u043f\u0442 \u043d\u0435 \u043f\u0430\u0434\u0430\u0435\u0442, \u0435\u0441\u043b\u0438 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0435 \u043f\u043e\u043b\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0435 \u0442\u0435\u043b\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>jsonField(\"anything\")<\/code> \u043f\u0440\u0438 \u0442\u0435\u043b\u0435 <code>\"not a json at all\"<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>null<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0417\u0430\u0449\u0438\u0442\u0430 \u043e\u0442 \u043f\u0430\u0434\u0435\u043d\u0438\u044f \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u0445 \u0431\u0435\u0437 JSON-\u0442\u0435\u043b\u0430<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0412\u0430\u0439\u043b\u0434\u043a\u0430\u0440\u0434 (<code>items[*].field<\/code>) \u0438 \u0444\u0438\u043b\u044c\u0442\u0440 (<code>items[?(@.field=='value')].field<\/code>) \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u0441\u043f\u0438\u0441\u043e\u043a, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435 \u0441\u043e\u0432\u043f\u0430\u043b \u0440\u043e\u0432\u043d\u043e \u043e\u0434\u0438\u043d \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u2014 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 <code>sum()<\/code>, <code>count()<\/code> \u0438 <code>avg()<\/code> \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d\u044b \u0438\u043c\u0435\u043d\u043d\u043e \u043d\u0430 \u0442\u0430\u043a\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u043d\u0430 \u0432\u0445\u043e\u0434\u0435, \u0430 \u043d\u0435 \u043d\u0430 \u0441\u043a\u0430\u043b\u044f\u0440\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0443\u0442\u044c \u0431\u0435\u0437 <code>[*]<\/code> \u0438\u043b\u0438 <code>[?(...)]<\/code>, \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442, \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0434\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 <code>null<\/code> \u2014 \u0441\u043c\u0435\u0448\u0438\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u0434\u0432\u0430 \u0440\u0435\u0436\u0438\u043c\u0430 \u0432 \u043e\u0434\u043d\u043e\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0438 \u043d\u0435\u043b\u044c\u0437\u044f<\/p>\n<p><a class=\"anchor\" name=\"daty-cherez-java-time-a-ne-vruchnuyu\" id=\"daty-cherez-java-time-a-ne-vruchnuyu\"><\/a><\/p>\n<h4>\u0414\u0430\u0442\u044b \u0447\u0435\u0440\u0435\u0437 java.time, \u0430 \u043d\u0435 \u0432\u0440\u0443\u0447\u043d\u0443\u044e<\/h4>\n<p>\u041a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 now() \u0438 nowPlusDays():<\/p>\n<pre><code class=\"java\">case \"now\": return Instant.now().toString();case \"nowPlusDays\": return Instant.now().plus((long) num(args, 0), ChronoUnit.DAYS).toString();<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code>now()<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 ISO-8601 (UTC), \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>2026-08-03T00:27:15.123Z<\/code>, \u0430 <code>nowPlusDays(n)<\/code> \u0431\u0435\u0440\u0451\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043a \u043d\u0435\u043c\u0443 <code>n<\/code> \u0441\u0443\u0442\u043e\u043a, \u0442\u043e\u0436\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 \u0442\u043e\u043c \u0436\u0435 \u0444\u043e\u0440\u043c\u0430\u0442\u0435. \u041a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 <code>random()<\/code>\/<code>uuid()<\/code> \u2014 \u044d\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b \u043e\u0442 <code>seed<\/code>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0431\u0435\u0440\u0443\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u0447\u0430\u0441\u043e\u0432 \u0447\u0435\u0440\u0435\u0437 <code>Instant.now()<\/code>, \u0430 \u043d\u0435 \u0438\u0437 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u043f\u0441\u0435\u0432\u0434\u043e\u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0445 \u0447\u0438\u0441\u0435\u043b \u2014 \u0432\u044b \u0443\u0436\u0435 \u0443\u0431\u0435\u0434\u0438\u043b\u0438\u0441\u044c \u0432 \u044d\u0442\u043e\u043c \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0441 \u0444\u0435\u0439\u043a\u043e\u0432\u044b\u043c \u0430\u0434\u0440\u0435\u0441\u043e\u043c \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438, \u0433\u0434\u0435 <code>createdAt<\/code> \u043c\u0435\u043d\u044f\u043b\u0441\u044f \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0432\u044b\u0437\u043e\u0432\u0435 \u0434\u0430\u0436\u0435 \u043f\u0440\u0438 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c <code>seed: 7<\/code>.<\/p>\n<p><strong>\u041f\u0440\u0438\u043c\u0435\u0440 \u2014 \u0434\u0430\u0442\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043a\u0430\u0437\u0430 \u0438 \u0441\u0440\u043e\u043a \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438<\/strong><\/p>\n<p>\u041f\u0440\u0430\u043a\u0442\u0438\u0447\u043d\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439: \u0441\u0435\u0440\u0432\u0438\u0441 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0437\u0430\u043a\u0430\u0437 \u0438 \u0441\u0440\u0430\u0437\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u0443\u044e \u0434\u0430\u0442\u0443 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0447\u0435\u0440\u0435\u0437 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u043d\u0435\u0439.<\/p>\n<p>\u0421\u043a\u0440\u0438\u043f\u0442:<\/p>\n<pre><code class=\"javascript\">var orderId = uuid();var createdAt = now();var estimatedDelivery = nowPlusDays(3);return {    \"status\": 200,    \"body\": {        \"orderId\": orderId,        \"createdAt\": createdAt,        \"estimatedDelivery\": estimatedDelivery    }};<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u0432 wiremock:<\/p>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/__admin\/extensions\/wiremock-js\/scripts \\  --header 'Content-Type: application\/json' \\  --data '{\"name\": \"Order with delivery estimate\",\"description\": \"\u0414\u0430\u0442\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043a\u0430\u0437\u0430 \u0438 \u0440\u0430\u0441\u0447\u0451\u0442\u043d\u0430\u044f \u0434\u0430\u0442\u0430 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0447\u0435\u0440\u0435\u0437 3 \u0434\u043d\u044f\",\"sourceCode\": \"var orderId = uuid(); var createdAt = now(); var estimatedDelivery = nowPlusDays(3); return { \\\"status\\\": 200, \\\"body\\\": { \\\"orderId\\\": orderId, \\\"createdAt\\\": createdAt, \\\"estimatedDelivery\\\": estimatedDelivery } };\"}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/d61\/ecb\/ddd\/d61ecbddd8ad89388445ec742ab9c83b.png\" alt=\"image-20260803003901425\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/d61\/ecb\/ddd\/d61ecbddd8ad89388445ec742ab9c83b.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/d61\/ecb\/ddd\/d61ecbddd8ad89388445ec742ab9c83b.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260803003901425<\/figcaption><\/div>\n<\/figure>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/__admin\/mappings \\  --header 'Content-Type: application\/json' \\  --data '{\"request\": {\"method\": \"POST\", \"urlPath\": \"\/api\/orders\/create\"}, \"response\": {\"status\": 200, \"transformers\": [\"wiremock-js\"], \"transformerParameters\": {\"scriptId\": \"804b0555-d1a0-4db7-b6cc-60a9d1af4eb7\"}}}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/131\/03a\/c84\/13103ac84f9c19dd9f4c66e1945ab940.png\" alt=\"image-20260803003942053\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/131\/03a\/c84\/13103ac84f9c19dd9f4c66e1945ab940.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/131\/03a\/c84\/13103ac84f9c19dd9f4c66e1945ab940.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260803003942053<\/figcaption><\/div>\n<\/figure>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/api\/orders\/create \\  --header 'Content-Type: application\/json' \\  --data '{\"amount\": 1500}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/aaf\/2a7\/29f\/aaf2a729f8cdfe084819b0d6d9c646ec.png\" alt=\"image-20260803004016820\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/aaf\/2a7\/29f\/aaf2a729f8cdfe084819b0d6d9c646ec.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/aaf\/2a7\/29f\/aaf2a729f8cdfe084819b0d6d9c646ec.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260803004016820<\/figcaption><\/div>\n<\/figure>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0424\u0443\u043d\u043a\u0446\u0438\u044f<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0421\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>now()<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>now() -&gt; String<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">ISO-8601 timestamp \u0441 \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u0430\u043c\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>\"2026-07-28T01:02:03.456Z\"<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>nowPlusDays(n)<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>nowPlusDays(Number) -&gt; String<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">ISO-8601 timestamp<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>n<\/code> \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c (\u0434\u0430\u0442\u0430 \u0432 \u043f\u0440\u043e\u0448\u043b\u043e\u043c)<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><a class=\"anchor\" name=\"uuid-i-randomint-s-oglyadkoy-na-determinizm\" id=\"uuid-i-randomint-s-oglyadkoy-na-determinizm\"><\/a><\/p>\n<h4>uuid() \u0438 randomInt() \u2014 \u0441 \u043e\u0433\u043b\u044f\u0434\u043a\u043e\u0439 \u043d\u0430 \u0434\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0438\u0437\u043c<\/h4>\n<p>\u0417\u0434\u0435\u0441\u044c \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0431\u044b\u043b\u043e \u0447\u0443\u0442\u044c \u043c\u0435\u043d\u0435\u0435 \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u043c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u0431\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u043b\u0438 \u043f\u043e\u0434\u0447\u0438\u043d\u044f\u0442\u044c\u0441\u044f \u043e\u0431\u0449\u0435\u043c\u0443 <code>seed<\/code>, \u0430 <code>UUID.randomUUID()<\/code> \u0438\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0441\u0432\u043e\u0439 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 <code>SecureRandom<\/code> \u0438 \u043d\u0435 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 <code>Random<\/code>. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 <code>uuid()<\/code> \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0438\u0437 \u0431\u0430\u0439\u0442\u043e\u0432 \u043e\u0431\u0449\u0435\u0433\u043e \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 <code>random<\/code>, \u0441 \u044f\u0432\u043d\u043e\u0439 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u043e\u0439 \u0431\u0438\u0442\u043e\u0432 \u0432\u0435\u0440\u0441\u0438\u0438 \u0438 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 UUID v4, \u0430 <code>randomInt(min, max)<\/code> \u2014 \u0447\u0435\u0440\u0435\u0437 <code>random.nextInt(max - min + 1) + min<\/code> \u0441 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439 <code>min &gt; max<\/code>:<\/p>\n<pre><code>javacase \"uuid\": return generateUuid();case \"randomInt\": return (double) randomInt((int) num(args, 0), (int) num(args, 1));<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418\u0437-\u0437\u0430 \u044d\u0442\u043e\u0433\u043e <code>uuid()<\/code> \u043f\u0440\u0438 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e\u043c <code>seed<\/code> \u0434\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d \u0440\u043e\u0432\u043d\u043e \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a <code>random()<\/code> \u2014 \u0432\u0435\u0441\u044c \u043d\u0430\u0431\u043e\u0440 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d \u043a \u043e\u0434\u043d\u043e\u043c\u0443 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0443, \u0438 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c\u044b\u043c\u0438 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0438\u0441\u043b\u043e\u0432\u044b\u0435 chaos-\u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438, \u043d\u043e \u0438 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u0441 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430\u043c\u0438 \u0432 CI\/CD.<\/p>\n<p>\u0422\u0443\u0442 \u0441\u0442\u043e\u0438\u0442 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0440\u0430\u0441c\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0440\u043e seed. \u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 seed \u043f\u0440\u043e\u0441\u0442\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438?<\/p>\n<p>\u041a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435 \u0443\u043c\u0435\u0435\u0442 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e-\u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u043c\u0443 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0435 \u0447\u0438\u0441\u043b\u0430 \u2014 \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u201c\u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0441\u0442\u044c\u044e\u201d \u0432 \u043a\u043e\u0434\u0435, \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0434\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u043c \u0448\u0430\u0433\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0447\u0438\u0441\u043b\u043e \u0438\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e. Seed (\u201c\u0437\u0435\u0440\u043d\u043e\u201d \u0438\u043b\u0438 \u201c\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e\u201d) \u2014 \u044d\u0442\u043e \u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440, \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u0441\u0432\u043e\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c: \u0435\u0441\u043b\u0438 \u0437\u0430\u0434\u0430\u0442\u044c \u043e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435 \u0437\u0435\u0440\u043d\u043e, \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u0432\u044b\u0434\u0430\u0441\u0442 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u0443\u044e \u0446\u0435\u043f\u043e\u0447\u043a\u0443 \u201c\u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0445\u201d \u0447\u0438\u0441\u0435\u043b, \u0430 \u0435\u0441\u043b\u0438 \u0437\u0435\u0440\u043d\u043e \u043d\u0435 \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u044f\u0432\u043d\u043e, \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043e\u0431\u044b\u0447\u043d\u043e \u0431\u0435\u0440\u0451\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u0438 \u0442\u043e\u0433\u0434\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a \u0434\u0430\u0451\u0442 \u0440\u0430\u0437\u043d\u0443\u044e, \u043d\u0435\u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u0443\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c.<\/p>\n<p>\u041d\u0430\u0433\u043b\u044f\u0434\u043d\u0430\u044f \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u044f \u2014 \u043a\u043d\u0438\u0433\u0430 \u0441 \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u043d\u0430\u043f\u0435\u0447\u0430\u0442\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u0447\u0438\u0441\u0435\u043b: seed \u2014 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u043e\u043c\u0435\u0440 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0447\u0438\u0442\u0430\u0442\u044c. \u041e\u0442\u043a\u0440\u044b\u0442\u044c \u043a\u043d\u0438\u0433\u0443 \u043d\u0430 42-\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0434\u0432\u0430 \u0440\u0430\u0437\u0430 \u043f\u043e\u0434\u0440\u044f\u0434 \u2014 \u0438 \u0432\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435 \u043e\u0434\u043d\u0438 \u0438 \u0442\u0435 \u0436\u0435 \u0447\u0438\u0441\u043b\u0430 \u0432 \u0442\u043e\u043c \u0436\u0435 \u043f\u043e\u0440\u044f\u0434\u043a\u0435; \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0431\u0435\u0437 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u2014 \u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0435 \u043c\u0435\u0441\u0442\u043e. \u041d\u0430 \u0445\u0430\u0431\u0440\u0435 \u0435\u0441\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u0438 \u043d\u0430 \u044d\u0442\u0443 \u0442\u0435\u043c\u0443: <a href=\"https:\/\/habr.com\/ru\/articles\/952192\/\" rel=\"noopener noreferrer nofollow\">habr<\/a><\/p>\n<p><a class=\"anchor\" name=\"zachem-seed-nuzhen-imenno-v-wiremockjs\" id=\"zachem-seed-nuzhen-imenno-v-wiremockjs\"><\/a><\/p>\n<h3>\u0417\u0430\u0447\u0435\u043c seed \u043d\u0443\u0436\u0435\u043d \u0438\u043c\u0435\u043d\u043d\u043e \u0432 WiremockJs<\/h3>\n<p>\u0412 \u043e\u0431\u044b\u0447\u043d\u043e\u043c \u043c\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u043d\u0435\u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u043e\u0441\u0442\u044c <code>random()<\/code> \u2014 \u044d\u0442\u043e \u0446\u0435\u043d\u043d\u043e\u0441\u0442\u044c: \u043e\u043d\u0430 \u0438\u043c\u0438\u0442\u0438\u0440\u0443\u0435\u0442 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u201c\u0448\u0443\u043c\u201d \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u041d\u043e \u0432 CI\/CD-\u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u0435 \u043d\u0435\u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u043e\u0441\u0442\u044c \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u2014 \u0435\u0441\u043b\u0438 \u0442\u0435\u0441\u0442 \u043d\u0430 retry-\u043b\u043e\u0433\u0438\u043a\u0443 \u0438\u043d\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 500, \u0430 \u0438\u043d\u043e\u0433\u0434\u0430 200 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043f\u0440\u043e\u0433\u043e\u043d \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u0430 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u043c (flaky), \u0438 \u043d\u0435\u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0431\u0430\u0433 \u043b\u0438 \u044d\u0442\u043e \u0432 \u0432\u0430\u0448\u0435\u043c \u043a\u043e\u0434\u0435 \u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u201c\u043d\u0435 \u043f\u043e\u0432\u0435\u0437\u043b\u043e\u201d \u0441 \u0440\u0430\u043d\u0434\u043e\u043c\u043e\u043c \u0432 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437.<\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 <code>ScriptDefinition<\/code> \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043e \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u043b\u0435 <code>seed<\/code> \u2014 \u0435\u0441\u043b\u0438 \u043e\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043e, \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0432\u043d\u0443\u0442\u0440\u0438 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0430 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u043a <code>new Random(seed)<\/code>, \u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u0442\u043e\u0433\u043e \u0436\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u0441 \u0442\u0435\u043c \u0436\u0435 <code>seed<\/code> \u0434\u0430\u0451\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u043d\u0443\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0443 <code>random()<\/code>, <code>randomInt()<\/code>, <code>uuid()<\/code> \u0438 <code>fake()<\/code>. \u0411\u0435\u0437 <code>seed<\/code> (\u043f\u043e\u043b\u0435 <code>null<\/code> \u0438\u043b\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442) \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0432\u0435\u0434\u0451\u0442 \u0441\u0435\u0431\u044f \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u044b\u0439 <code>Math.random()<\/code> \u2014 \u043d\u0435\u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u043e \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a. \u042d\u0442\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u043e \u0442\u0435\u0441\u0442\u043e\u043c <code>shouldBeDeterministicWithSameSeed<\/code>, \u0433\u0434\u0435 \u0434\u0432\u0430 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0445 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0430 \u0441 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c <code>seed = 42<\/code> \u0434\u0430\u044e\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u043d\u044b\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b <code>random()<\/code> \u0442\u0440\u0438\u0436\u0434\u044b \u043f\u043e\u0434\u0440\u044f\u0434, \u0430 \u0442\u0435\u0441\u0442 <code>shouldDifferWithDifferentSeeds<\/code> \u0441 <code>seed = 1<\/code> \u0438 <code>seed = 2<\/code> \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0440\u0430\u0441\u0445\u043e\u0434\u044f\u0442\u0441\u044f.<\/p>\n<pre><code class=\"java\">    @Test    @DisplayName(\"random() \u0441 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c seed \u0434\u0430\u0451\u0442 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u0443\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\")    void shouldBeDeterministicWithSameSeed() {        String script = \"\"\"        return { \"a\": random(), \"b\": random(), \"c\": random() };        \"\"\";        WiremockJsInterpreter interpreter1 = new WiremockJsInterpreter(new RequestFacade(mockRequest));        WiremockJsInterpreter interpreter2 = new WiremockJsInterpreter(new RequestFacade(mockRequest));        Map&lt;String, Object&gt; result1 = interpreter1.execute(script, 42);        Map&lt;String, Object&gt; result2 = interpreter2.execute(script, 42);        assertEquals(result1.get(\"a\"), result2.get(\"a\"));        assertEquals(result1.get(\"b\"), result2.get(\"b\"));        assertEquals(result1.get(\"c\"), result2.get(\"c\"));    }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"json\">{  \"name\": \"Chaos 5 percent errors\",  \"sourceCode\": \"if (random() &lt; 0.05) { return { \\\"status\\\": 500 }; } else { return { \\\"status\\\": 200 }; }\",  \"seed\": 42}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421 \u044d\u0442\u0438\u043c <code>seed: 42<\/code> \u043a\u0430\u0436\u0434\u044b\u0439 \u043f\u0440\u043e\u0433\u043e\u043d CI \u043f\u0440\u043e\u0442\u0438\u0432 \u043e\u0434\u043d\u043e\u0433\u043e \u0438 \u0442\u043e\u0433\u043e \u0436\u0435 \u0441\u0442\u0430\u0431\u0430 \u0434\u0430\u0451\u0442 \u043e\u0434\u043d\u0443 \u0438 \u0442\u0443 \u0436\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u201c\u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0445\u201d \u043e\u0448\u0438\u0431\u043e\u043a \u2014 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u0430\u0436\u0435 \u0442\u0430\u043c, \u0433\u0434\u0435 \u043f\u043e \u0441\u043c\u044b\u0441\u043b\u0443 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043d\u0435\u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u043e\u0441\u0442\u044c.<\/p>\n<p>\u0421\u043e\u0431\u0435\u0440\u0451\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u043d\u0430 chaos-\u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u0441 <code>seed<\/code>, \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u043a\u0440\u0438\u043f\u0442, \u043f\u0440\u0438\u0432\u044f\u0436\u0435\u043c \u0435\u0433\u043e \u043a \u0441\u0442\u0430\u0431\u0443 \u0438 \u0432\u044b\u0437\u043e\u0432\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437, \u0447\u0442\u043e\u0431\u044b \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0434\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0438\u0437\u043c \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435.<\/p>\n<p><a class=\"anchor\" name=\"shag-1-sozdaem-skript-s-seed\" id=\"shag-1-sozdaem-skript-s-seed\"><\/a><\/p>\n<h3>\u0428\u0430\u0433 1 \u2014 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u043a\u0440\u0438\u043f\u0442 \u0441 seed<\/h3>\n<pre><code class=\"bash\">curl -X POST http:\/\/localhost:8888\/__admin\/extensions\/wiremock-js\/scripts \\  -H \"Content-Type: application\/json\" \\  -d '{    \"name\": \"Chaos with seed demo\",    \"description\": \"\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0434\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0438\u0437\u043c\u0430 random() \u0438 uuid() \u043f\u0440\u0438 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u043c seed\",    \"sourceCode\": \"if (random() &lt; 0.3) { return { \\\"status\\\": 500, \\\"body\\\": { \\\"error\\\": \\\"internal error\\\", \\\"requestId\\\": uuid() } }; } else { return { \\\"status\\\": 200, \\\"body\\\": { \\\"ok\\\": true, \\\"requestId\\\": uuid() } }; }\",    \"seed\": 42  }'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u043e\u0442\u0432\u0435\u0442\u0435 \u043f\u0440\u0438\u0434\u0451\u0442 <code>scriptId<\/code>, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>a1b2c3d4-...<\/code> \u2014 \u0435\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u0441\u0442\u0430\u0431 \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0448\u0430\u0433\u0435. \u0423 \u043c\u0435\u043d\u044f \u044d\u0442\u043e 9e0a8a67-424d-47f4-8fbc-f1afa8736b49.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/1ad\/257\/89b\/1ad25789b9ea18339dce7a3c790497c7.png\" alt=\"image-20260802164009648\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/1ad\/257\/89b\/1ad25789b9ea18339dce7a3c790497c7.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/1ad\/257\/89b\/1ad25789b9ea18339dce7a3c790497c7.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802164009648<\/figcaption><\/div>\n<\/figure>\n<p><a class=\"anchor\" name=\"shag-2-sozdaem-stab-privyazannyy-k-skriptu\" id=\"shag-2-sozdaem-stab-privyazannyy-k-skriptu\"><\/a><\/p>\n<h3>\u0428\u0430\u0433 2 \u2014 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u0442\u0430\u0431, \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0439 \u043a \u0441\u043a\u0440\u0438\u043f\u0442\u0443<\/h3>\n<pre><code class=\"bash\">curl -X POST http:\/\/localhost:8888\/__admin\/mappings \\  -H \"Content-Type: application\/json\" \\  -d '{    \"request\": { \"method\": \"GET\", \"urlPath\": \"\/api\/chaos\/demo\" },    \"response\": {      \"status\": 200,      \"transformers\": [\"wiremock-js\"],      \"transformerParameters\": { \"scriptId\": \"&lt;ID \u0438\u0437 \u0448\u0430\u0433\u0430 1&gt;\" }    }  }'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/a89\/fc0\/632\/a89fc0632b82d4c767baf1fbf686f1cf.png\" alt=\"image-20260802164118934\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/a89\/fc0\/632\/a89fc0632b82d4c767baf1fbf686f1cf.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/a89\/fc0\/632\/a89fc0632b82d4c767baf1fbf686f1cf.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802164118934<\/figcaption><\/div>\n<\/figure>\n<p><a class=\"anchor\" name=\"shag-3-vyzyvaem-stab-neskolko-raz\" id=\"shag-3-vyzyvaem-stab-neskolko-raz\"><\/a><\/p>\n<h3>\u0428\u0430\u0433 3 \u2014 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0441\u0442\u0430\u0431 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437<\/h3>\n<pre><code class=\"bash\">curl http:\/\/localhost:8888\/api\/chaos\/democurl http:\/\/localhost:8888\/api\/chaos\/democurl http:\/\/localhost:8888\/api\/chaos\/demo<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/07b\/1d2\/26f\/07b1d226f5064ea5bf65cb1d6981d28e.png\" alt=\"image-20260802165650835\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/07b\/1d2\/26f\/07b1d226f5064ea5bf65cb1d6981d28e.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/07b\/1d2\/26f\/07b1d226f5064ea5bf65cb1d6981d28e.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802165650835<\/figcaption><\/div>\n<\/figure>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/a37\/16c\/ab4\/a3716cab4c4522b6ec56909205e6d183.png\" alt=\"image-20260802165701711\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/a37\/16c\/ab4\/a3716cab4c4522b6ec56909205e6d183.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/a37\/16c\/ab4\/a3716cab4c4522b6ec56909205e6d183.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802165701711<\/figcaption><\/div>\n<\/figure>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/e3c\/ade\/345\/e3cade345d22a68d39e0058ea5f23e38.png\" alt=\"image-20260802171500886\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/e3c\/ade\/345\/e3cade345d22a68d39e0058ea5f23e38.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/e3c\/ade\/345\/e3cade345d22a68d39e0058ea5f23e38.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802171500886<\/figcaption><\/div>\n<\/figure>\n<p><a class=\"anchor\" name=\"kak-eto-vedet-sebya-na-praktike\" id=\"kak-eto-vedet-sebya-na-praktike\"><\/a><\/p>\n<h3>\u041a\u0430\u043a \u044d\u0442\u043e \u0432\u0435\u0434\u0451\u0442 \u0441\u0435\u0431\u044f \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435<\/h3>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 <code>seed = 42<\/code> \u0437\u0430\u0434\u0430\u043d \u044f\u0432\u043d\u043e, \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0432\u043d\u0443\u0442\u0440\u0438 <code>WiremockJsInterpreter<\/code> \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u043a <code>new Random(42)<\/code> \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u0441\u043a\u0440\u0438\u043f\u0442\u0430, \u0430 \u043d\u0435 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043c\u0435\u0436\u0434\u0443 \u0432\u044b\u0437\u043e\u0432\u0430\u043c\u0438 \u2014 \u0442\u043e \u0435\u0441\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440 \u0441 \u043d\u0443\u043b\u044f, \u0438 <code>random()<\/code> \u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u0436\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0438 \u0432\u043d\u0443\u0442\u0440\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u0438 \u0442\u043e\u0433\u043e \u0436\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u0441 \u043e\u0434\u043d\u0438\u043c \u0438 \u0442\u0435\u043c \u0436\u0435 <code>seed<\/code> \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435 \u043f\u0435\u0440\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u043f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u043a\u043e\u0434\u0435 \u0432\u0441\u0435 \u0442\u0440\u0438 curl-\u0432\u044b\u0437\u043e\u0432\u0430 \u0432\u044b\u0448\u0435 \u0434\u0430\u0434\u0443\u0442 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u2014 \u043b\u0438\u0431\u043e \u0432\u0441\u0435\u0433\u0434\u0430 <code>{\"status\": 500, ...}<\/code>, \u043b\u0438\u0431\u043e \u0432\u0441\u0435\u0433\u0434\u0430 <code>{\"status\": 200, ...}<\/code>, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a\u043e\u0435 \u043f\u0435\u0440\u0432\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0434\u0430\u0451\u0442 <code>new Random(42).nextDouble()<\/code>.<\/p>\n<p>\u0415\u0441\u043b\u0438 seed \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d \u0442\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u0432\u044b\u0437\u043e\u0432  \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u0438\u043b\u0438 200 \u0441\u0442\u0430\u0442\u0443\u0441 \u043e\u0442\u0432\u0435\u0442\u0430 \u0438\u043b\u0438 500 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u0443\u0441\u043b\u043e\u0432\u0438\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u0430. \u0421\u0443\u0442\u044c <code>seed<\/code> \u2014 \u043e\u043d \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u201c\u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u044b\u043c \u043e\u0434\u0438\u043d \u0432\u044b\u0437\u043e\u0432\u201d, \u0430 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0432\u0435\u0441\u044c \u0441\u043a\u0440\u0438\u043f\u0442 \u0432 \u0447\u0438\u0441\u0442\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043e\u0442 seed: \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0432\u0445\u043e\u0434 \u0432\u0441\u0435\u0433\u0434\u0430 \u0434\u0430\u0451\u0442 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0432\u044b\u0445\u043e\u0434, \u0447\u0442\u043e \u0443\u0434\u043e\u0431\u043d\u043e \u0434\u043b\u044f \u044e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u043e\u0432, \u043d\u043e \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u043e \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u0431\u0435\u0437 \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u044f \u0436\u0434\u0451\u0442 \u043e\u0442 <code>uuid()<\/code> \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0432\u044b\u0437\u043e\u0432.<\/p>\n<p><a class=\"anchor\" name=\"matches-str-pattern\" id=\"matches-str-pattern\"><\/a><\/p>\n<h4>matches(str, pattern)<\/h4>\n<p>\u0412\u0430\u0436\u043d\u043e \u043f\u043e\u043c\u043d\u0438\u0442\u044c, \u0447\u0442\u043e <code>matches()<\/code> \u0432 WiremockJs \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 <strong>\u043f\u043e\u043b\u043d\u043e\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0439 \u0441\u0442\u0440\u043e\u043a\u0438<\/strong> \u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u043c (\u0447\u0435\u0440\u0435\u0437 RE2J, \u0430 \u043d\u0435 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 <code>java.util.regex<\/code>), \u0438 \u044d\u0442\u043e \u0442\u043e\u0447\u044c-\u0432-\u0442\u043e\u0447\u044c \u043a\u0430\u043a <code>Pattern.matches()<\/code> \u2014 \u0431\u0435\u0437 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e\u0433\u043e \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u043e\u0434\u0441\u0442\u0440\u043e\u043a\u0438.<\/p>\n<p><a class=\"anchor\" name=\"primer-1-validaciya-formata-telefona-pered-obrabotkoy-zakaza\" id=\"primer-1-validaciya-formata-telefona-pered-obrabotkoy-zakaza\"><\/a><\/p>\n<h3>\u041f\u0440\u0438\u043c\u0435\u0440 1 \u2014 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u0444\u043e\u0440\u043c\u0430\u0442\u0430 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430 \u043f\u0435\u0440\u0435\u0434 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 \u0437\u0430\u043a\u0430\u0437\u0430<\/h3>\n<p>\u041f\u0440\u0430\u043a\u0442\u0438\u0447\u043d\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439: \u0441\u0435\u0440\u0432\u0438\u0441 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0437\u0430\u043a\u0430\u0437 \u0438 \u0434\u043e\u043b\u0436\u0435\u043d \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043d\u043e\u043c\u0435\u0440 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u043c\u0443 \u0444\u043e\u0440\u043c\u0430\u0442\u0443, \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0437\u0430\u044f\u0432\u043a\u0443.<\/p>\n<p>\u0421\u043a\u0440\u0438\u043f\u0442:<\/p>\n<pre><code class=\"javascript\">var phone = jsonField(\"phone\");if (!matches(phone, \"\\\\+7\\\\d{10}\")) {    return {        \"status\": 400,        \"body\": {            \"error\": \"invalid phone format\",            \"expected\": \"+7XXXXXXXXXX\"        }    };}return {    \"status\": 200,    \"body\": {        \"orderId\": uuid(),        \"phone\": phone,        \"status\": \"CREATED\"    }};<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/__admin\/extensions\/wiremock-js\/scripts \\  --header 'Content-Type: application\/json' \\  --data '{\"name\": \"Validate phone format\",\"sourceCode\": \"var phone = jsonField(\\\"phone\\\"); if (!matches(phone, \\\"\\\\+7\\\\d{10}\\\")) { return { \\\"status\\\": 400, \\\"body\\\": { \\\"error\\\": \\\"invalid phone format\\\", \\\"expected\\\": \\\"+7XXXXXXXXXX\\\" } }; } return { \\\"status\\\": 200, \\\"body\\\": { \\\"orderId\\\": uuid(), \\\"phone\\\": phone, \\\"status\\\": \\\"CREATED\\\" } };\"}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/df9\/afa\/10e\/df9afa10ebe0857ea832322c152f84cd.png\" alt=\"image-20260803010019847\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/df9\/afa\/10e\/df9afa10ebe0857ea832322c152f84cd.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/df9\/afa\/10e\/df9afa10ebe0857ea832322c152f84cd.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260803010019847<\/figcaption><\/div>\n<\/figure>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/__admin\/mappings \\  --header 'Content-Type: application\/json' \\  --data '{\"request\": {\"method\": \"POST\",\"urlPath\": \"\/api\/orders\/validate-phone\"},\"response\": {\"status\": 200,\"transformers\": [\"wiremock-js\"],\"transformerParameters\": {\"scriptId\": \"ae807684-a5db-4fe0-b3d0-33b1ee88264e\"}}}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/7ac\/892\/32a\/7ac89232ad7fc2443a26cf4adf7e15d8.png\" alt=\"image-20260803010043854\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/7ac\/892\/32a\/7ac89232ad7fc2443a26cf4adf7e15d8.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/7ac\/892\/32a\/7ac89232ad7fc2443a26cf4adf7e15d8.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260803010043854<\/figcaption><\/div>\n<\/figure>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/api\/orders\/validate-phone \\  --header 'Content-Type: application\/json' \\  --data '{\"phone\": \"+79161234567\"}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/e39\/e23\/108\/e39e231087b03eb27d7c09e4058879e1.png\" alt=\"image-20260803010119331\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/e39\/e23\/108\/e39e231087b03eb27d7c09e4058879e1.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/e39\/e23\/108\/e39e231087b03eb27d7c09e4058879e1.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260803010119331<\/figcaption><\/div>\n<\/figure>\n<p><a class=\"anchor\" name=\"primer-2-bolee-slozhnyy-primer-v-kotorom-realizovana-marshrutizaciya-po-neskolkim-formatam-telefona\" id=\"primer-2-bolee-slozhnyy-primer-v-kotorom-realizovana-marshrutizaciya-po-neskolkim-formatam-telefona\"><\/a><\/p>\n<h3>\u041f\u0440\u0438\u043c\u0435\u0440 2 &#8212; \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0430\u043c \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430<\/h3>\n<p>\u0421\u043a\u0440\u0438\u043f\u0442:<\/p>\n<details class=\"spoiler\">\n<summary>\u041c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0430\u043c \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">var phone = jsonField(\"phone\");if (matches(phone, \"\\\\+79\\\\d{9}\")) {    return {        \"status\": 200,        \"body\": {            \"phone\": phone,            \"country\": \"RU\",            \"type\": \"mobile\",            \"valid\": true        }    };}if (matches(phone, \"\\\\+7[34568]\\\\d{9}\")) {    return {        \"status\": 200,        \"body\": {            \"phone\": phone,            \"country\": \"RU\",            \"type\": \"landline\",            \"valid\": true        }    };}if (matches(phone, \"8\\\\d{10}\")) {    return {        \"status\": 200,        \"body\": {            \"phone\": phone,            \"country\": \"RU\",            \"type\": \"mobile_legacy_format\",            \"valid\": true,            \"warning\": \"use +7 format instead\"        }    };}if (matches(phone, \"\\\\+1\\\\d{10}\")) {    return {        \"status\": 200,        \"body\": {            \"phone\": phone,            \"country\": \"US\",            \"type\": \"mobile\",            \"valid\": true        }    };}return {    \"status\": 400,    \"body\": {        \"phone\": phone,        \"valid\": false,        \"error\": \"unrecognized phone format\"    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/__admin\/extensions\/wiremock-js\/scripts \\  --header 'Content-Type: application\/json' \\  --data '{  \"name\": \"Phone classifier\",  \"description\": \"\u041a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442 \u043d\u043e\u043c\u0435\u0440 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430 \u043f\u043e \u0444\u043e\u0440\u043c\u0430\u0442\u0443 \u0438 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0443\",  \"sourceCode\": \"var phone = jsonField(\\\"phone\\\"); if (matches(phone, \\\"\\\\+79\\\\d{9}\\\")) { return { \\\"status\\\": 200, \\\"body\\\": { \\\"phone\\\": phone, \\\"country\\\": \\\"RU\\\", \\\"type\\\": \\\"mobile\\\", \\\"valid\\\": true } }; } if (matches(phone, \\\"\\\\+7[34568]\\\\d{9}\\\")) { return { \\\"status\\\": 200, \\\"body\\\": { \\\"phone\\\": phone, \\\"country\\\": \\\"RU\\\", \\\"type\\\": \\\"landline\\\", \\\"valid\\\": true } }; } if (matches(phone, \\\"8\\\\d{10}\\\")) { return { \\\"status\\\": 200, \\\"body\\\": { \\\"phone\\\": phone, \\\"country\\\": \\\"RU\\\", \\\"type\\\": \\\"mobile_legacy_format\\\", \\\"valid\\\": true, \\\"warning\\\": \\\"use +7 format instead\\\" } }; } if (matches(phone, \\\"\\\\+1\\\\d{10}\\\")) { return { \\\"status\\\": 200, \\\"body\\\": { \\\"phone\\\": phone, \\\"country\\\": \\\"US\\\", \\\"type\\\": \\\"mobile\\\", \\\"valid\\\": true } }; } return { \\\"status\\\": 400, \\\"body\\\": { \\\"phone\\\": phone, \\\"valid\\\": false, \\\"error\\\": \\\"unrecognized phone format\\\" } };\"}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/371\/0c4\/af9\/3710c4af9f5756a773d95e98fd9a203e.png\" alt=\"image-20260803011148247\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/371\/0c4\/af9\/3710c4af9f5756a773d95e98fd9a203e.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/371\/0c4\/af9\/3710c4af9f5756a773d95e98fd9a203e.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260803011148247<\/figcaption><\/div>\n<\/figure>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/__admin\/mappings \\  --header 'Content-Type: application\/json' \\  --data '{\"request\": {\"method\": \"POST\",\"urlPath\": \"\/api\/phones\/classify\"},\"response\": {\"status\": 200,\"transformers\": [\"wiremock-js\"],\"transformerParameters\": {\"scriptId\": \"f3358922-faed-4159-9538-263e43a99d77\"}}}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/7ff\/366\/98c\/7ff36698c145bda4aa357605be08a342.png\" alt=\"image-20260803011222740\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/7ff\/366\/98c\/7ff36698c145bda4aa357605be08a342.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/7ff\/366\/98c\/7ff36698c145bda4aa357605be08a342.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260803011222740<\/figcaption><\/div>\n<\/figure>\n<p>\u0420\u043e\u0441\u0441\u0438\u0439\u0441\u043a\u0438\u0439 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0439 (+7 9XX):<\/p>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/api\/phones\/classify \\  --header 'Content-Type: application\/json' \\  --data '{\"phone\": \"+79161234567\"}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code class=\"json\">{ \"phone\": \"+79161234567\", \"country\": \"RU\", \"type\": \"mobile\", \"valid\": true }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0420\u043e\u0441\u0441\u0438\u0439\u0441\u043a\u0438\u0439 \u0441\u0442\u0430\u0446\u0438\u043e\u043d\u0430\u0440\u043d\u044b\u0439 (+7, \u043d\u043e \u043d\u0435 9):<\/p>\n<pre><code class=\"bash\">curl --request POST --url http:\/\/localhost:8888\/api\/phones\/classify --header 'Content-Type: application\/json' --data '{\"phone\": \"+74951234567\"}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code class=\"json\">{ \"phone\": \"+74951234567\", \"country\": \"RU\", \"type\": \"landline\", \"valid\": true }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0423\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 \u0441 8 \u0432\u043c\u0435\u0441\u0442\u043e +7:<\/p>\n<pre><code class=\"bash\">curl --request POST --url http:\/\/localhost:8888\/api\/phones\/classify --header 'Content-Type: application\/json' --data '{\"phone\": \"89161234567\"}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code class=\"json\">{ \"phone\": \"89161234567\", \"country\": \"RU\", \"type\": \"mobile_legacy_format\", \"valid\": true, \"warning\": \"use +7 format instead\" }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410\u043c\u0435\u0440\u0438\u043a\u0430\u043d\u0441\u043a\u0438\u0439 \u043d\u043e\u043c\u0435\u0440:<\/p>\n<pre><code class=\"bash\">curl --request POST --url http:\/\/localhost:8888\/api\/phones\/classify --header 'Content-Type: application\/json' --data '{\"phone\": \"+12025551234\"}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code class=\"json\">{ \"phone\": \"+12025551234\", \"country\": \"US\", \"type\": \"mobile\", \"valid\": true }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0435\u043e\u043f\u043e\u0437\u043d\u0430\u043d\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442<\/p>\n<pre><code class=\"bash\">curl --request POST --url http:\/\/localhost:8888\/api\/phones\/classify --header 'Content-Type: application\/json' --data '{\"phone\": \"12345\"}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code class=\"json\">{ \"phone\": \"12345\", \"valid\": false, \"error\": \"unrecognized phone format\" }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/strong>:<\/p>\n<p>\u0413\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0430 WiremockJs \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u0442 STRING-\u0442\u043e\u043a\u0435\u043d \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 escape-\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0435\u0439 (<code>'\"' (~[\"\\\\] | '\\\\' .)* '\"'<\/code>), \u0447\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043e\u0431\u043c\u0430\u043d\u0447\u0438\u0432\u043e\u0435 \u0432\u043f\u0435\u0447\u0430\u0442\u043b\u0435\u043d\u0438\u0435, \u0431\u0443\u0434\u0442\u043e <code>\\n<\/code>, <code>\\t<\/code> \u0438\u043b\u0438 <code>\\\"<\/code> \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0442\u0440\u043e\u043a\u0438 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u044f\u0442\u0441\u044f \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u0441\u0442\u0440\u043e\u043a\u0438, \u0442\u0430\u0431\u0443\u043b\u044f\u0446\u0438\u044e \u0438\u043b\u0438 \u043a\u0430\u0432\u044b\u0447\u043a\u0443. \u041d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u044d\u0442\u043e \u043d\u0435 \u0442\u0430\u043a: \u043c\u0435\u0442\u043e\u0434 <code>unquote()<\/code> \u0432 <code>WiremockJsInterpreter<\/code> \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0440\u0435\u0437\u0430\u0435\u0442 \u043f\u043e\u0434\u0441\u0442\u0440\u043e\u043a\u0443 \u043c\u0435\u0436\u0434\u0443 \u043f\u0435\u0440\u0432\u043e\u0439 \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u043a\u0430\u0432\u044b\u0447\u043a\u043e\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \u0432 \u0441\u0438\u043c\u0432\u043e\u043b, \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u0443\u044f backslash \u2014 \u0442\u043e \u0435\u0441\u0442\u044c \u043b\u0438\u0442\u0435\u0440\u0430\u043b <code>\"\\\\n\"<\/code> \u0432 \u0441\u043a\u0440\u0438\u043f\u0442\u0435 \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u0434\u0432\u0443\u043c\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u043c\u0438 <code>\\<\/code> \u0438 <code>n<\/code>, \u0430 \u043d\u0435 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u0441\u044f \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u0441\u0442\u0440\u043e\u043a\u0438.<\/p>\n<p>\u042d\u0442\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043a\u0440\u0438\u0442\u0438\u0447\u043d\u043e \u0434\u043b\u044f \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0432 <code>matches()<\/code>. \u041a\u043e\u0433\u0434\u0430 \u0432\u044b \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0435 \u0441\u043a\u0440\u0438\u043f\u0442 \u0447\u0435\u0440\u0435\u0437 curl \u0432 JSON-\u0442\u0435\u043b\u0435 \u0432\u0438\u0434\u0430 <code>\"sourceCode\": \"matches(phone, \\\"\\\\\\\\+7\\\\\\\\d{10}\\\")\"<\/code>, \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0434\u0432\u0430 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0445 \u0441\u043b\u043e\u044f \u044d\u043a\u0440\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<ul>\n<li>\n<p>JSON-\u043f\u0430\u0440\u0441\u0435\u0440 \u043d\u0430 \u0432\u0445\u043e\u0434\u0435 (\u043f\u0440\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0438 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u0447\u0435\u0440\u0435\u0437 Admin API) \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>\\\\\\\\+7\\\\\\\\d{10}<\/code> \u0432 \u0441\u0442\u0440\u043e\u043a\u0443 <code>\\+7\\d{10}<\/code> \u2014 \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 backslash \u043f\u0435\u0440\u0435\u0434 \u043a\u0430\u0436\u0434\u044b\u043c \u0441\u043f\u0435\u0446\u0441\u0438\u043c\u0432\u043e\u043b\u043e\u043c.<\/p>\n<\/li>\n<li>\n<p>WiremockJs-\u043f\u0430\u0440\u0441\u0435\u0440 \u043f\u0440\u0438 \u0440\u0430\u0437\u0431\u043e\u0440\u0435 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u0433\u043e \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u0430 <code>\"\\+7\\d{10}\"<\/code> \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u043d\u0435 \u0442\u0440\u043e\u0433\u0430\u0435\u0442 backslash \u0432\u043e\u043e\u0431\u0449\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e <code>unquote()<\/code> \u043d\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f escape-\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 \u2014 \u0438\u0442\u043e\u0433\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u043f\u0430\u0434\u0451\u0442 \u0432 <code>matches()<\/code>, \u0431\u0443\u0434\u0435\u0442 \u0440\u043e\u0432\u043d\u043e <code>\\+7\\d{10}<\/code>, \u0447\u0442\u043e \u0438 \u043d\u0443\u0436\u043d\u043e RE2J \u043a\u0430\u043a \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d.<\/p>\n<\/li>\n<\/ul>\n<p><a class=\"anchor\" name=\"zachem-ponadobilsya-re2j\" id=\"zachem-ponadobilsya-re2j\"><\/a><\/p>\n<h3>\u0417\u0430\u0447\u0435\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u043b\u0441\u044f RE2J<\/h3>\n<p>\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>matches(str, pattern)<\/code> \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0441\u0442\u0440\u043e\u043a\u0438 \u043d\u0430 regex \u0441\u043e\u0437\u0434\u0430\u043b\u0430 \u043d\u043e\u0432\u044b\u0439 \u0440\u0438\u0441\u043a \u2014 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 ReDoS \u0447\u0435\u0440\u0435\u0437 catastrophic backtracking \u0432 <code>java.util.regex<\/code>. \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0430\u044f: \u0437\u043b\u043e\u0439 \u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u044b\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d \u0442\u0438\u043f\u0430 <code>(a+)+<\/code> \u0432 \u0441\u0432\u044f\u0437\u043a\u0435 \u0441\u043e \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u0438\u0437 \u043f\u043e\u043b\u0443\u0441\u043e\u0442\u043d\u0438 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 <code>a<\/code> \u0438 \u0431\u0435\u0437 \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0434\u0432\u0438\u0436\u043e\u043a \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043e\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u044d\u043a\u0441\u043f\u043e\u043d\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0433\u043e, \u0430 \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 <code>matches()<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u0437 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430, \u044d\u0442\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u0430\u044f \u0434\u0432\u0435\u0440\u044c \u0434\u043b\u044f DoS \u0447\u0435\u0440\u0435\u0437 \u0441\u0430\u043c \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u043c\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<details class=\"spoiler\">\n<summary>matches() \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043a\u0430\u0442\u0430\u0441\u0442\u0440\u043e\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d \u0431\u0435\u0437 \u0437\u0430\u0432\u0438\u0441\u0430\u043d\u0438\u044f<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">@Test@DisplayName(\"matches() \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043a\u0430\u0442\u0430\u0441\u0442\u0440\u043e\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d \u0431\u0435\u0437 \u0437\u0430\u0432\u0438\u0441\u0430\u043d\u0438\u044f\")void shouldHandleCatastrophicPatternSafely() {    String script = \"\"\"    if (matches(\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!\", \"(a+)+b\")) {      return { \"valid\": true };    } else {      return { \"valid\": false };    }    \"\"\";    long start = System.currentTimeMillis();    Map&lt;String, Object&gt; result = run(script);    long elapsed = System.currentTimeMillis() - start;    assertEquals(false, result.get(\"valid\"));    assertTrue(elapsed &lt; 500);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p>\u042f \u044d\u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e \u0442\u0435\u0441\u0442\u043e\u043c \u0441 ReDoS-\u043f\u0430\u0442\u0442\u0435\u0440\u043d\u043e\u043c \u2014 \u0441\u0442\u0440\u043e\u043a\u0430 \u0438\u0437 ~150 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 <code>a<\/code> \u043f\u043b\u044e\u0441 <code>!<\/code> \u0432 \u043a\u043e\u043d\u0446\u0435 \u043f\u0440\u043e\u0442\u0438\u0432 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430 <code>(a+)+$<\/code>, \u0438 \u0441 <code>java.util.regex<\/code> \u0442\u0430\u043a\u043e\u0439 \u0432\u0432\u043e\u0434 \u0437\u0430\u0432\u0438\u0441 \u0431\u044b \u043d\u0430 \u043d\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u0430 \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u0432 100 \u043c\u0441 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 <code>CompletableFuture<\/code> \u0432 <code>ScriptTransformer<\/code> \u0442\u0443\u0442 \u043d\u0435 \u0441\u043f\u0430\u0441\u0430\u0435\u0442 \u043f\u043e-\u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u043c\u0443: <code>future.cancel(true)<\/code> \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u0440\u0432\u0430\u0442\u044c \u043f\u043e\u0442\u043e\u043a \u0447\u0435\u0440\u0435\u0437 <code>Thread.interrupt()<\/code>, \u043d\u043e <code>Matcher<\/code> \u0438\u0437 <code>java.util.regex<\/code> \u043d\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0444\u043b\u0430\u0433 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f backtracking-\u0446\u0438\u043a\u043b\u0430, \u0438 \u043f\u043e\u0442\u043e\u043a \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u0436\u0435\u0447\u044c CPU \u0434\u0430\u0436\u0435 \u043f\u043e\u0441\u043b\u0435 \u201c\u043e\u0442\u043c\u0435\u043d\u044b\u201d.<\/p>\n<p>\u0420\u0435\u0448\u0438\u043b \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0434\u0432\u0438\u0436\u043e\u043a \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043e\u043a \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u043d\u0430 <code>com.google.re2j:re2j:1.7<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 Google RE2: \u0432\u043c\u0435\u0441\u0442\u043e backtracking \u0442\u0430\u043c DFA-\u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0441 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u043b\u0438\u043d\u0435\u0439\u043d\u044b\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f O(n) \u043e\u0442 \u0434\u043b\u0438\u043d\u044b \u0441\u0442\u0440\u043e\u043a\u0438, \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430. \u041f\u043b\u0430\u0442\u0430 \u0437\u0430 \u044d\u0442\u0443 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u044e \u2014 RE2J \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 backreferences (<code>\\1<\/code>, <code>\\2<\/code>) \u0438 \u0447\u0430\u0441\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u044b\u0445 lookahead\/lookbehind \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439, \u043d\u043e \u0434\u043b\u044f \u0442\u0438\u043f\u043e\u0432\u044b\u0445 \u0437\u0430\u0434\u0430\u0447 \u043c\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f (email, \u0442\u0435\u043b\u0435\u0444\u043e\u043d, \u0444\u043e\u0440\u043c\u0430\u0442 ID) \u044d\u0442\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e:<\/p>\n<pre><code>dependencies {    implementation 'com.google.re2j:re2j:1.7'}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code class=\"java\">case \"matches\": {                    String input = str(args, 0);                    String pattern = str(args, 1);                    if (input == null || pattern == null) {                        return false;                    }                    try {                        return com.google.re2j.Pattern.matches(pattern, input);                    } catch (com.google.re2j.PatternSyntaxException e) {                        throw new ScriptExecutionException(\"\u041d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0435 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435: \" + e.getMessage());                    }                }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><a class=\"anchor\" name=\"fake-zaglushka-dlya-realistichnyh-dannyh\" id=\"fake-zaglushka-dlya-realistichnyh-dannyh\"><\/a><\/p>\n<h4>fake() \u2014 \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0430 \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0441\u0442\u0438\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445<\/h4>\n<p>\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f \u043f\u0440\u043e\u0431\u0435\u043b\u0430 \u2014 \u0440\u0435\u0430\u043b\u0438\u0441\u0442\u0438\u0447\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 (\u0438\u043c\u0435\u043d\u0430, email, \u0430\u0434\u0440\u0435\u0441\u0430), \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u0435 \u0431\u044b\u043b\u043e \u0431\u044b \u0443\u0442\u043e\u043c\u0438\u0442\u0435\u043b\u044c\u043d\u043e. \u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u2014 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c DataFaker \u0438 \u043f\u0440\u043e\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>fake(pattern)<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u0443\u0435\u0442 \u0432\u0441\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044e DataFaker:<\/p>\n<pre><code class=\"java\">case \"fake\": {    String pattern = str(args, 0);    if (pattern == null) throw new ScriptExecutionException(\"fake(): \u0448\u0430\u0431\u043b\u043e\u043d \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c null\");    try {        return faker.expression(pattern);    } catch (Exception e) {        throw new ScriptExecutionException(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435 fake(\\\"\" + pattern + \"\\\"): \" + e.getMessage());    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u0430 \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u044f \u0443\u0441\u0438\u043b\u0438\u0439 \u2014 \u0432\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u0434\u0443\u043c\u044b\u0432\u0430\u0442\u044c whitelist \u0438\u0437 \u0434\u0435\u0441\u044f\u0442\u043a\u043e\u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 (<code>fakeName()<\/code>, <code>fakeEmail()<\/code>, <code>fakeAddress()<\/code>\u2026), \u044f \u043f\u0440\u043e\u043a\u0438\u043d\u0443\u043b \u0432 \u044f\u0437\u044b\u043a \u0440\u043e\u0432\u043d\u043e \u043e\u0434\u043d\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d DataFaker (<code>\"Name.firstName\"<\/code>, <code>\"Internet.emailAddress\"<\/code>) \u0438 \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u0443\u0435\u0442 \u0432\u0441\u044e \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u0430\u043c\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435. \u041a\u0430\u043a \u0438 <code>uuid()<\/code>, <code>fake()<\/code> \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441 \u0442\u0435\u043c \u0436\u0435 <code>seed<\/code>, \u0447\u0442\u043e \u0434\u0430\u0451\u0442 <code>Faker<\/code> \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 repeatable-\u0434\u0430\u043d\u043d\u044b\u0445 \u2014 \u0441\u043d\u043e\u0432\u0430 \u0442\u043e\u0442 \u0436\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u201c\u043e\u0434\u0438\u043d seed \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u0441\u0435\u0439 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u043a\u0440\u0438\u043f\u0442\u0430\u201d.<\/p>\n<p><a class=\"anchor\" name=\"primer-1-prostaya-generaciya-klienta\" id=\"primer-1-prostaya-generaciya-klienta\"><\/a><\/p>\n<h3>\u041f\u0440\u0438\u043c\u0435\u0440 1 \u2014 \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430<\/h3>\n<p>\u0421\u0430\u043c\u044b\u0439 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439: \u0441\u0435\u0440\u0432\u0438\u0441 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0433\u043e, \u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0441\u0442\u0438\u0447\u043d\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0435.<\/p>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/__admin\/extensions\/wiremock-js\/scripts \\  --header 'Content-Type: application\/json' \\  --data '{\"name\": \"Fake customer\",\"description\": \"\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0447\u0435\u0440\u0435\u0437 DataFaker\",\"sourceCode\": \"var firstName = fake(\\\"#{Name.first_name}\\\"); var lastName = fake(\\\"#{Name.last_name}\\\"); var email = fake(\\\"#{Internet.email_address}\\\"); return { \\\"status\\\": 200, \\\"body\\\": { \\\"id\\\": uuid(), \\\"firstName\\\": firstName, \\\"lastName\\\": lastName, \\\"email\\\": email } };\"}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/__admin\/mappings \\  --header 'Content-Type: application\/json' \\  --data '{\"request\": {\"method\": \"GET\",\"urlPath\": \"\/api\/customers\/random\"},\"response\": {\"status\": 200,\"transformers\": [\"wiremock-js\"],\"transformerParameters\": {\"scriptId\": \"&lt;ID&gt;\"}}}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code class=\"bash\">curl http:\/\/localhost:8888\/api\/customers\/random<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u0432\u0435\u0440\u043d\u0451\u0442 \u043d\u043e\u0432\u043e\u0435 \u0438\u043c\u044f, \u0444\u0430\u043c\u0438\u043b\u0438\u044e \u0438 email \u2014 \u0431\u0435\u0437 <code>seed<\/code> \u044d\u0442\u043e \u043f\u043e-\u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u043c\u0443 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/0c4\/10f\/818\/0c410f8183714e1deb953a254177ace6.png\" alt=\"image-20260802173523491\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/0c4\/10f\/818\/0c410f8183714e1deb953a254177ace6.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/0c4\/10f\/818\/0c410f8183714e1deb953a254177ace6.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802173523491<\/figcaption><\/div>\n<\/figure>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/8d9\/b37\/d0e\/8d9b37d0ef53d939ce62a7b01dff6fa2.png\" alt=\"image-20260802173538694\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/8d9\/b37\/d0e\/8d9b37d0ef53d939ce62a7b01dff6fa2.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/8d9\/b37\/d0e\/8d9b37d0ef53d939ce62a7b01dff6fa2.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802173538694<\/figcaption><\/div>\n<\/figure>\n<p><a class=\"anchor\" name=\"primer-2-determinirovannyy-feykovyy-zakaz-cherez-seed\" id=\"primer-2-determinirovannyy-feykovyy-zakaz-cherez-seed\"><\/a><\/p>\n<h3>\u041f\u0440\u0438\u043c\u0435\u0440 2 \u2014 \u0434\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0444\u0435\u0439\u043a\u043e\u0432\u044b\u0439 \u0437\u0430\u043a\u0430\u0437 \u0447\u0435\u0440\u0435\u0437 seed<\/h3>\n<p>\u0417\u0434\u0435\u0441\u044c \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0432\u044f\u0437\u043a\u0430 <code>fake()<\/code> + <code>seed<\/code> \u2014 \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432, \u0433\u0434\u0435 \u043d\u0443\u0436\u043d\u044b \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0435, \u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0441\u0442\u0438\u0447\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435:<\/p>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/__admin\/extensions\/wiremock-js\/scripts \\  --header 'Content-Type: application\/json' \\  --data '{\"name\": \"Fake order with fixed seed\",\"description\": \"\u041e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0444\u0435\u0439\u043a\u043e\u0432\u044b\u0439 \u0430\u0434\u0440\u0435\u0441 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u043f\u0440\u043e\u0433\u043e\u043d\u0435 \u0442\u0435\u0441\u0442\u0430\",\"sourceCode\": \"var city = fake(\\\"#{Address.city}\\\"); var street = fake(\\\"#{Address.street_address}\\\"); return { \\\"status\\\": 200, \\\"body\\\": { \\\"orderId\\\": uuid(), \\\"deliveryAddress\\\": { \\\"city\\\": city, \\\"street\\\": street }, \\\"createdAt\\\": now() } };\",\"seed\": 7}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/__admin\/mappings \\  --header 'Content-Type: application\/json' \\  --data '{\"request\": {\"method\": \"GET\",\"urlPath\": \"\/api\/orders\/fake\"},\"response\": {\"status\": 200,\"transformers\": [\"wiremock-js\"],\"transformerParameters\": {\"scriptId\": \"&lt;ID&gt;\"}}}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code class=\"bash\">curl --request GET --url http:\/\/localhost:8888\/api\/orders\/fake<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/ee9\/4c1\/3e2\/ee94c13e22b09a169cf0c6a624f925a0.png\" alt=\"image-20260802174147354\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/ee9\/4c1\/3e2\/ee94c13e22b09a169cf0c6a624f925a0.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/ee9\/4c1\/3e2\/ee94c13e22b09a169cf0c6a624f925a0.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802174147354<\/figcaption><\/div>\n<\/figure>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/9d5\/56f\/8d9\/9d556f8d9c8e86cb9a96b922ac515d2a.png\" alt=\"image-20260802174201356\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/9d5\/56f\/8d9\/9d556f8d9c8e86cb9a96b922ac515d2a.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/9d5\/56f\/8d9\/9d556f8d9c8e86cb9a96b922ac515d2a.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802174201356<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 <code>Faker<\/code> \u0432\u043d\u0443\u0442\u0440\u0438 <code>Visitor<\/code> \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u0441 \u0442\u0435\u043c \u0436\u0435 <code>Random(seed)<\/code>, \u0447\u0442\u043e \u0438 <code>uuid()<\/code>, \u043f\u0440\u0438 <code>seed: 7<\/code> \u043a\u0430\u0436\u0434\u044b\u0439 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u044d\u0442\u043e\u0433\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u0434\u0430\u0441\u0442 \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 <code>city<\/code>, <code>street<\/code> \u0438 <code>orderId<\/code> \u2014 \u0430 \u0432\u043e\u0442 <code>createdAt<\/code> \u0431\u0443\u0434\u0435\u0442 \u0432\u0441\u0435\u0433\u0434\u0430 \u043d\u043e\u0432\u044b\u043c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e <code>now()<\/code> \u0431\u0435\u0440\u0451\u0442 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u0430 \u043d\u0435 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0445 \u0447\u0438\u0441\u0435\u043b.<\/p>\n<p><a class=\"anchor\" name=\"primer-3-sochetanie-fake-s-realnymi-dannymi-iz-zaprosa\" id=\"primer-3-sochetanie-fake-s-realnymi-dannymi-iz-zaprosa\"><\/a><\/p>\n<h3>\u041f\u0440\u0438\u043c\u0435\u0440 3 \u2014 \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0435 fake() \u0441 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438\u0437 \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/h3>\n<p>\u0411\u043e\u043b\u0435\u0435 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u043d\u044b\u0439 \u043a\u0435\u0439\u0441 \u2014 \u0442\u0435\u043b\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e \u0438\u0437 \u0432\u0445\u043e\u0434\u043d\u043e\u0433\u043e JSON, \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e \u0438\u0437 faker, \u0447\u0442\u043e \u0442\u0438\u043f\u0438\u0447\u043d\u043e \u0434\u043b\u044f webhook-\u0438\u043c\u0438\u0442\u0430\u0446\u0438\u0439:<\/p>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/__admin\/extensions\/wiremock-js\/scripts \\  --header 'Content-Type: application\/json' \\  --data '{\"name\": \"Payment webhook with fake merchant\",\"description\": \"paymentId \u0431\u0435\u0440\u0451\u0442\u0441\u044f \u0438\u0437 \u0437\u0430\u043f\u0440\u043e\u0441\u0430, merchant \u0434\u0430\u043d\u043d\u044b\u0435 \u2014 \u0444\u0435\u0439\u043a\u043e\u0432\u044b\u0435\",\"sourceCode\": \"var paymentId = jsonField(\\\"paymentId\\\"); if (paymentId == null) { return { \\\"status\\\": 400, \\\"body\\\": { \\\"error\\\": \\\"paymentId is required\\\" } }; } var merchantName = fake(\\\"#{Company.name}\\\"); return { \\\"status\\\": 200, \\\"body\\\": { \\\"paymentId\\\": paymentId, \\\"status\\\": \\\"COMPLETED\\\", \\\"merchant\\\": merchantName, \\\"processedAt\\\": now() } };\"}'  curl --request POST \\  --url http:\/\/localhost:8888\/__admin\/mappings \\  --header 'Content-Type: application\/json' \\  --data '{\"request\": {\"method\": \"POST\",\"urlPath\": \"\/api\/payments\/webhook\"},\"response\": {\"status\": 200,\"transformers\": [\"wiremock-js\"],\"transformerParameters\": {\"scriptId\": \"&lt;ID&gt;\"}}}'  curl --request POST \\  --url http:\/\/localhost:8888\/api\/payments\/webhook \\  --header 'Content-Type: application\/json' \\  --data '{\"paymentId\": \"pay_12345\"}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/930\/c72\/170\/930c72170817733b42cf8583cd92975a.png\" alt=\"image-20260802174732358\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/930\/c72\/170\/930c72170817733b42cf8583cd92975a.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/930\/c72\/170\/930c72170817733b42cf8583cd92975a.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802174732358<\/figcaption><\/div>\n<\/figure>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/d7a\/e02\/f34\/d7ae02f347c57229b8a1cdd3bb34db8b.png\" alt=\"image-20260802174835964\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/d7a\/e02\/f34\/d7ae02f347c57229b8a1cdd3bb34db8b.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/d7a\/e02\/f34\/d7ae02f347c57229b8a1cdd3bb34db8b.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802174835964<\/figcaption><\/div>\n<\/figure>\n<pre><code class=\"json\">{  \"paymentId\": \"pay_12345\",  \"status\": \"COMPLETED\",  \"merchant\": \"&lt;\u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438&gt;\",  \"processedAt\": \"&lt;\u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f&gt;\"}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u044b\u0437\u043e\u0432:<\/p>\n<pre><code class=\"bash\">curl-X POST http:\/\/localhost:8888\/api\/payments\/webhook -H \"Content-Type: application\/json\" -d '{}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u0439 \u043e\u0442\u0432\u0435\u0442 \u2014 HTTP 400:<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/d11\/696\/8fe\/d116968fe2e74aff693b6e22918479b8.png\" alt=\"image-20260802174910120\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/d11\/696\/8fe\/d116968fe2e74aff693b6e22918479b8.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/d11\/696\/8fe\/d116968fe2e74aff693b6e22918479b8.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802174910120<\/figcaption><\/div>\n<\/figure>\n<p>\u0417\u0434\u0435\u0441\u044c <code>jsonField(\"paymentId\")<\/code> \u0447\u0438\u0442\u0430\u0435\u0442 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430, <code>fake(\"Company.name\")<\/code> \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0441\u0442\u0438\u0447\u043d\u044b\u0439, \u043d\u043e \u043d\u0435 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442, \u0430 <code>if (paymentId == null)<\/code> \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0443\u0436\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u0443\u044e \u043d\u0430\u043c \u0437\u0430\u0449\u0438\u0442\u0443 \u043e\u0442 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043f\u043e\u043b\u0435\u0439.<\/p>\n<p><a class=\"anchor\" name=\"poleznye-shablony-datafaker-dlya-spravki\" id=\"poleznye-shablony-datafaker-dlya-spravki\"><\/a><\/p>\n<h3>\u041f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u044b DataFaker \u0434\u043b\u044f \u0441\u043f\u0440\u0430\u0432\u043a\u0438<\/h3>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0428\u0430\u0431\u043b\u043e\u043d<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0440\u0438\u043c\u0435\u0440 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 (EN)<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0440\u0438\u043c\u0435\u0440 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 (RU)<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u043e\u043b\u043d\u043e\u0435 \u0438\u043c\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>#{Name.full_name}<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">Miss Samanta Schmidt<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0418\u0432\u0430\u043d\u043e\u0432\u0430 \u041c\u0430\u0440\u0438\u044f \u041f\u0435\u0442\u0440\u043e\u0432\u043d\u0430<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0418\u043c\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>#{Name.first_name}<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">Norman<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041c\u0430\u0440\u0438\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0424\u0430\u043c\u0438\u043b\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>#{Name.last_name}<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">O\u2019Reilly<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0418\u0432\u0430\u043d\u043e\u0432\u0430<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Email<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>#{Internet.email_address}<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"mailto:ralph.keebler@yahoo.com\" rel=\"noopener noreferrer nofollow\">ralph.keebler@yahoo.com<\/a><\/p>\n<\/td>\n<td>\n<p align=\"left\"><a href=\"mailto:maria.ivanova@yandex.ru\" rel=\"noopener noreferrer nofollow\">maria.ivanova@yandex.ru<\/a><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0414\u043e\u043c\u0435\u043d<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>#{Internet.domain_name}<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">example.com<\/p>\n<\/td>\n<td>\n<p align=\"left\">example.ru<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041a\u043e\u043c\u043f\u0430\u043d\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>#{Company.name}<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">Mohamedland Inc.<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0410\u041e \u0418\u0432\u0430\u043d\u043e\u0432\u043e\u0421\u0431\u044b\u0442\u0421\u043d\u0430\u0431\u0421\u0431\u044b\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0421\u043b\u043e\u0433\u0430\u043d \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>#{Company.catch_phrase}<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">Innovative solutions for tomorrow<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0418\u043d\u043d\u043e\u0432\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0431\u0443\u0434\u0443\u0449\u0435\u0433\u043e<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0413\u043e\u0440\u043e\u0434<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>#{Address.city}<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">Mohamedland<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041c\u043e\u0441\u043a\u0432\u0430<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u043e\u043b\u043d\u044b\u0439 \u0430\u0434\u0440\u0435\u0441<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>#{Address.full_address}<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">4890 Homenick Junctions, Springfield<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0433. \u041c\u043e\u0441\u043a\u0432\u0430, \u0443\u043b. \u041b\u0435\u043d\u0438\u043d\u0430, \u0434. 15<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0423\u043b\u0438\u0446\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>#{Address.street_address}<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">4890 Homenick Junctions<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0443\u043b. \u041b\u0435\u043d\u0438\u043d\u0430, \u0434. 15<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u043e\u0447\u0442\u043e\u0432\u044b\u0439 \u0438\u043d\u0434\u0435\u043a\u0441<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>#{Address.zip_code}<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">90210<\/p>\n<\/td>\n<td>\n<p align=\"left\">101000<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0421\u0442\u0440\u0430\u043d\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>#{Address.country}<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">Suriname<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0420\u043e\u0441\u0441\u0438\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0422\u0435\u043b\u0435\u0444\u043e\u043d<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>#{PhoneNumber.phone_number}<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">+1-555-0134<\/p>\n<\/td>\n<td>\n<p align=\"left\">+7-900-123-45-67<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435 (\u0442\u0435\u043a\u0441\u0442)<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>#{Lorem.sentence}<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435 (\u043e\u0431\u044b\u0447\u043d\u043e \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c, \u0434\u0430\u0436\u0435 \u0432 ru-\u043b\u043e\u043a\u0430\u043b\u0438)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0421\u043b\u043e\u0432\u043e<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>#{Lorem.word}<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">apple<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u044f\u0431\u043b\u043e\u043a\u043e<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041d\u043e\u043c\u0435\u0440 \u043a\u0440\u0435\u0434\u0438\u0442\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u044b<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>#{Finance.credit_card}<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">4111-1111-1111-1111<\/p>\n<\/td>\n<td>\n<p align=\"left\">4111-1111-1111-1111<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0432\u0430\u043b\u044e\u0442\u044b<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>#{Money.currency}<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">USD<\/p>\n<\/td>\n<td>\n<p align=\"left\">RUB<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>#{Job.title}<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">Software Engineer<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0418\u043d\u0436\u0435\u043d\u0435\u0440-\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">UUID (\u0447\u0435\u0440\u0435\u0437 Faker)<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>#{Internet.uuid}<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u043c\u0443 <code>uuid()<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u043c\u0443 <code>uuid()<\/code><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435:<\/p>\n<p>\u0412 \u043f\u043b\u0430\u0433\u0438\u043d\u0435 \u044f \u0437\u0430\u0448\u0438\u043b \u0445\u0430\u0440\u0434\u043a\u043e\u0440\u043d\u043e RU \u043b\u043e\u043a\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u0444\u0435\u0439\u043a\u043e\u0432\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<pre><code class=\"java\">public class FakerHolder {    private static volatile Faker instance;    public static synchronized Faker getInstance() {        if (instance == null) {            instance = new Faker(new Locale(\"ru\"));        }        return instance;    }    private FakerHolder() {}}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e EN \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0441 \u044d\u0442\u0438\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c. \u041d\u0435 \u0432\u044b\u043d\u043e\u0441\u0438\u043b \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043b \u043f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438 \u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0430\u0445 \u0438 \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c UI. \u0410 \u0442\u0430\u043c \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043d\u044c\u044e\u0430\u043d\u0441\u044b \u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u044f \u0435\u0449\u0435 \u043d\u0435 \u043f\u043e\u0434\u043e\u0437\u0440\u0435\u0432\u0430\u044e.<\/p>\n<p><a class=\"anchor\" name=\"kombinirovanie-neskolkih-znacheniy-v-odnom-vyzove\" id=\"kombinirovanie-neskolkih-znacheniy-v-odnom-vyzove\"><\/a><\/p>\n<h3>\u041a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0432 \u043e\u0434\u043d\u043e\u043c \u0432\u044b\u0437\u043e\u0432\u0435<\/h3>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 <code>expression()<\/code> \u0438\u0449\u0435\u0442 \u0432\u0441\u0435 \u043f\u043e\u0434\u0441\u0442\u0440\u043e\u043a\u0438 <code>#{...}<\/code> \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430, \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0446\u0435\u043b\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u0438\u043c \u0432\u044b\u0437\u043e\u0432\u043e\u043c <code>fake()<\/code>, \u0431\u0435\u0437 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u043a\u0430\u043a \u0432\u044b \u0443\u0436\u0435 \u0432\u0438\u0434\u0435\u043b\u0438 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0441 merchant:<\/p>\n<pre><code class=\"json\">\"sourceCode\": \"var summary = fake(\\\"\u041a\u043b\u0438\u0435\u043d\u0442 #{Name.full_name} \u0438\u0437 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 #{Company.name}, email: #{Internet.email_address}\\\"); return { \\\"status\\\": 200, \\\"body\\\": { \\\"summary\\\": summary } };\"<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u2014 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0432\u0435\u0440\u0441\u0438\u0438 DataFaker (<code>1.9.0<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043d\u043e\u0442\u0430\u0446\u0438\u044e <code>Category.method_name<\/code> \u0447\u0435\u0440\u0435\u0437 <code>snake_case<\/code>, \u0442\u043e\u0433\u0434\u0430 \u043a\u0430\u043a \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u043f\u043e\u0434 <code>2.x<\/code> \u0441 \u0434\u0440\u0443\u0433\u0438\u043c \u0441\u0442\u0438\u043b\u0435\u043c) \u2014 \u0435\u0441\u043b\u0438 <code>fake(...)<\/code> \u0431\u0440\u043e\u0441\u0430\u0435\u0442 <code>ScriptExecutionException<\/code> \u0441 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c \u043f\u0440\u043e \u043d\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440, \u0441\u0442\u043e\u0438\u0442 \u0441\u0432\u0435\u0440\u0438\u0442\u044c\u0441\u044f \u0441 \u0442\u043e\u0447\u043d\u044b\u043c \u0441\u043f\u0438\u0441\u043a\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u0434\u043b\u044f \u0432\u0435\u0440\u0441\u0438\u0438 <code>1.9.0<\/code>, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u044b \u0441\u0435\u0439\u0447\u0430\u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 \u043f\u043e\u0441\u043b\u0435 downgrade<\/p>\n<p><a class=\"anchor\" name=\"mapkeys-pereimenovanie-poley-bez-polnocennogo-eval\" id=\"mapkeys-pereimenovanie-poley-bez-polnocennogo-eval\"><\/a><\/p>\n<h4>mapKeys() \u2014 \u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u0435\u0439 \u0431\u0435\u0437 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0433\u043e eval<\/h4>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0448\u0442\u0440\u0438\u0445 \u0432 \u044d\u0442\u043e\u0439 \u0432\u043e\u043b\u043d\u0435 \u2014 \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043b\u044e\u0447\u0435\u0439 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, API \u043e\u0442\u0434\u0430\u0451\u0442 <code>{\"cost\": 100}<\/code>, \u0430 \u0442\u0435\u0441\u0442 \u043e\u0436\u0438\u0434\u0430\u0435\u0442 <code>{\"price\": 100}<\/code>). \u041f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f (<code>map(array, item =&gt; ...)<\/code>) \u043e\u0437\u043d\u0430\u0447\u0430\u043b\u043e \u0431\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 eval-\u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0438 \u0432 \u044f\u0437\u044b\u043a, \u0430 \u044d\u0442\u043e \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u0440\u0435\u0447\u0438\u043b\u043e \u0432\u0441\u0435\u0439 \u0438\u0434\u0435\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e\u0433\u043e DSL \u2014 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0443\u0437\u043a\u0443\u044e, \u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>mapKeys(array, mapping)<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u044b\u0432\u0430\u0435\u0442 \u043a\u043b\u044e\u0447\u0438 \u043f\u043e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c\u0443 \u0441\u043b\u043e\u0432\u0430\u0440\u044e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0439, \u0431\u0435\u0437 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442.<\/p>\n<p><a class=\"anchor\" name=\"agregirovannye-funkcii\" id=\"agregirovannye-funkcii\"><\/a><\/p>\n<h4>\u0410\u0433\u0440\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/h4>\n<p><a class=\"anchor\" name=\"pochemu-agregirovannye-funkcii\" id=\"pochemu-agregirovannye-funkcii\"><\/a><\/p>\n<h3>\u041f\u043e\u0447\u0435\u043c\u0443 \u0430\u0433\u0440\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/h3>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043f\u0440\u0438\u0447\u0438\u043d\u0430 \u2014 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0432 \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0435. \u0426\u0438\u043a\u043b\u044b (<code>for<\/code>, <code>while<\/code>) \u0432 \u044f\u0437\u044b\u043a\u0435, \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u043c \u0432 HTTP-\u043c\u043e\u043a-\u0441\u0435\u0440\u0432\u0435\u0440, \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u044e\u0442 \u043f\u0440\u044f\u043c\u043e\u0439 \u043f\u0443\u0442\u044c \u043a runaway-\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044e: \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c <code>while (true) {}<\/code> \u0438\u043b\u0438 \u0446\u0438\u043a\u043b \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439 \u0432 \u0443\u0441\u043b\u043e\u0432\u0438\u0438 \u0432\u044b\u0445\u043e\u0434\u0430, \u0438 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0437\u0430\u0449\u0438\u0442\u0430 \u043e\u0442 \u0437\u0430\u0432\u0438\u0441\u0448\u0435\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430 \u2014 \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u0432 <code>ScriptTransformer<\/code> (<code>EXECUTION_TIMEOUT_MS<\/code>), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0435\u0442 <code>Future<\/code>, \u043d\u043e \u043d\u0435 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442, \u0447\u0442\u043e \u043f\u043e\u0442\u043e\u043a \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043c\u0433\u043d\u043e\u0432\u0435\u043d\u043d\u043e \u0438 \u043d\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442 \u0436\u0440\u0430\u0442\u044c CPU \u0432 \u0444\u043e\u043d\u0435. \u042f \u0443\u0436\u0435 \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u043b\u0438\u0441\u044f \u0441 \u0442\u0435\u043c, \u043a\u0430\u043a \u0447\u0443\u0432\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u0435\u043d \u044d\u0442\u043e\u0442 \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u2014 \u0434\u0430\u0436\u0435 100 \u043c\u0441 \u0445\u043e\u043b\u043e\u0434\u043d\u043e\u0433\u043e \u0441\u0442\u0430\u0440\u0442\u0430 <code>Faker<\/code> \u043b\u043e\u0432\u0438\u043b \u043e\u0448\u0438\u0431\u043a\u0443, \u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u0431\u0435\u0437 \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439 \u2014 \u043a\u0443\u0434\u0430 \u0431\u043e\u043b\u0435\u0435 \u0441\u0435\u0440\u044c\u0451\u0437\u043d\u044b\u0439 \u0440\u0438\u0441\u043a \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d-\u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430 WireMock, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0441\u0442\u0430\u0431\u043e\u0432 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e<\/p>\n<p><code>sum()<\/code>, <code>count()<\/code> \u0438 <code>avg()<\/code> \u0440\u0435\u0448\u0430\u044e\u0442 \u0442\u0443 \u0436\u0435 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u2014 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u2014 \u043d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c:<\/p>\n<ul>\n<li>\n<p><strong>\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u044b \u043f\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044e<\/strong> \u2014 \u043e\u043d\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0442 \u0440\u043e\u0432\u043d\u043e \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u0441\u043f\u0438\u0441\u043a\u0443 \u043e\u0434\u0438\u043d \u0440\u0430\u0437, \u0431\u0435\u0437 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0439 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>\u041d\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u0442\u0435\u043b\u0430 \u0446\u0438\u043a\u043b\u0430<\/strong> \u2014 \u0432\u0441\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u0438 \u0437\u0430\u0448\u0438\u0442\u0430 \u0432 <code>sumOf()<\/code>, \u0430 \u043d\u0435 \u0432 \u0441\u043a\u0440\u0438\u043f\u0442\u0435, \u0437\u043d\u0430\u0447\u0438\u0442 \u043d\u0435\u0442 \u0440\u0438\u0441\u043a\u0430, \u0447\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430\u043f\u0438\u0448\u0435\u0442 \u0432\u043d\u0443\u0442\u0440\u0438 \u0446\u0438\u043a\u043b\u0430 \u0447\u0442\u043e-\u0442\u043e \u0442\u044f\u0436\u0451\u043b\u043e\u0435 \u0438\u043b\u0438 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e\u0435.<\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u044b \u043f\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f<\/strong> \u2014 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c <code>O(n)<\/code> \u043e\u0442 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u043c\u0430\u0441\u0441\u0438\u0432\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438 \u0442\u0430\u043a \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c \u0442\u0435\u043b\u0430 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u0430 \u043d\u0435 \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u0435\u043d, \u043a\u0430\u043a \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0433\u043e <code>while<\/code>.<\/p>\n<\/li>\n<\/ul>\n<p><a class=\"anchor\" name=\"kak-eto-rabotaet-pod-kapotom\" id=\"kak-eto-rabotaet-pod-kapotom\"><\/a><\/p>\n<h3>\u041a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c<\/h3>\n<p>\u0412\u0441\u0435 \u0442\u0440\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442 \u043e\u0434\u0438\u043d \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u2014 \u043c\u0430\u0441\u0441\u0438\u0432 (<code>List&lt;Object&gt;<\/code>), \u043e\u0431\u044b\u0447\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0447\u0435\u0440\u0435\u0437 <code>jsonField()<\/code> \u0441 wildcard-\u043f\u0443\u0442\u0451\u043c \u0442\u0438\u043f\u0430 <code>orders.price<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u0435 \u043e\u0434\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0430 \u0441\u043f\u0438\u0441\u043e\u043a \u0447\u0438\u0441\u0435\u043b \u0438\u0437 \u0432\u0441\u0435\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0430:<\/p>\n<pre><code class=\"java\">case \"sum\": return sumOf(args.get(0));case \"count\": return (double) toList(args.get(0)).size();case \"avg\": {    List&lt;Object&gt; list = toList(args.get(0));    if (list.isEmpty()) {        throw new ScriptExecutionException(\"avg(): \u043f\u0443\u0441\u0442\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432\");    }    return sumOf(args.get(0)) \/ list.size();}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code>sum()<\/code> \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443 \u0441\u043f\u0438\u0441\u043a\u0430 \u0447\u0435\u0440\u0435\u0437 <code>sumOf()<\/code> \u0438 \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u0438\u0445 \u043a\u0430\u043a \u0447\u0438\u0441\u043b\u0430 (\u0441 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u043c \u0442\u0438\u043f\u043e\u0432 \u0447\u0435\u0440\u0435\u0437 <code>num()<\/code>), <code>count()<\/code> \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u043f\u0438\u0441\u043a\u0430 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e, \u0430 <code>avg()<\/code> \u0434\u0435\u043b\u0438\u0442 \u0441\u0443\u043c\u043c\u0443 \u043d\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u2014 \u0441 \u044f\u0432\u043d\u043e\u0439 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 \u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043d\u0430 \u043d\u043e\u043b\u044c, \u0435\u0441\u043b\u0438 \u043c\u0430\u0441\u0441\u0438\u0432 \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043f\u0443\u0441\u0442\u044b\u043c. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0432\u0430\u0436\u043d\u0443\u044e \u0434\u0435\u0442\u0430\u043b\u044c: <code>avg()<\/code> \u0431\u0440\u043e\u0441\u0430\u0435\u0442 <code>ScriptExecutionException<\/code> \u043f\u0440\u0438 \u043f\u0443\u0441\u0442\u043e\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u0435, \u0430 \u043d\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>NaN<\/code> \u0438\u043b\u0438 <code>0<\/code> \u2014 \u044d\u0442\u043e \u043e\u0441\u043e\u0437\u043d\u0430\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0443 \u044f\u0432\u043d\u043e\u0439, \u0430 \u043d\u0435 \u043c\u043e\u043b\u0447\u0430 \u0437\u0430\u043c\u0430\u0441\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0432 \u0434\u0430\u043d\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u0430.<\/p>\n<p><a class=\"anchor\" name=\"primer-1-summa-i-kolichestvo-tovarov-v-zakaze\" id=\"primer-1-summa-i-kolichestvo-tovarov-v-zakaze\"><\/a><\/p>\n<h3>\u041f\u0440\u0438\u043c\u0435\u0440 1 \u2014 \u0441\u0443\u043c\u043c\u0430 \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0442\u043e\u0432\u0430\u0440\u043e\u0432 \u0432 \u0437\u0430\u043a\u0430\u0437\u0435<\/h3>\n<p>\u041f\u0440\u0430\u043a\u0442\u0438\u0447\u043d\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439: \u043a\u043b\u0438\u0435\u043d\u0442 \u043f\u0440\u0438\u0441\u044b\u043b\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0442\u043e\u0432\u0430\u0440\u043e\u0432 \u0441 \u0446\u0435\u043d\u0430\u043c\u0438, \u0430 \u0441\u0442\u0430\u0431 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043e\u0431\u0449\u0443\u044e \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c \u0437\u0430\u043a\u0430\u0437\u0430 \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0437\u0438\u0446\u0438\u0439.<\/p>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/__admin\/extensions\/wiremock-js\/scripts \\  --header 'Content-Type: application\/json' \\  --data '{\"name\": \"Order total calculator\",\"sourceCode\": \"var prices = jsonField(\\\"items[*].price\\\"); var total = sum(prices); var itemsCount = count(prices); return { \\\"status\\\": 200, \\\"body\\\": { \\\"totalPrice\\\": total, \\\"itemsCount\\\": itemsCount } };\"}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/165\/8b1\/97e\/1658b197e379ec69376b483fbf532a73.png\" alt=\"image-20260802230105456\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/165\/8b1\/97e\/1658b197e379ec69376b483fbf532a73.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/165\/8b1\/97e\/1658b197e379ec69376b483fbf532a73.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802230105456<\/figcaption><\/div>\n<\/figure>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/__admin\/mappings \\  --header 'Content-Type: application\/json' \\  --data '{\"request\": {\"method\": \"POST\",\"urlPath\": \"\/api\/orders\/calculate\"},\"response\": {\"status\": 200,\"transformers\": [\"wiremock-js\"],\"transformerParameters\": {\"scriptId\": \"&lt;ScriptID&gt;\"}}}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/f85\/9e2\/f72\/f859e2f7258290de4eacdd7f9592e100.png\" alt=\"image-20260802230238209\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/f85\/9e2\/f72\/f859e2f7258290de4eacdd7f9592e100.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/f85\/9e2\/f72\/f859e2f7258290de4eacdd7f9592e100.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802230238209<\/figcaption><\/div>\n<\/figure>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/api\/orders\/calculate \\  --header 'Content-Type: application\/json' \\  --data '{\"items\": [{\"price\": 100},{\"price\": 250},{\"price\": 50}]}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/d28\/7a4\/f74\/d287a4f743683b4dbaa3e9c69b574c05.png\" alt=\"image-20260802230252953\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/d28\/7a4\/f74\/d287a4f743683b4dbaa3e9c69b574c05.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/d28\/7a4\/f74\/d287a4f743683b4dbaa3e9c69b574c05.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802230252953<\/figcaption><\/div>\n<\/figure>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<pre><code class=\"json\">{  \"totalPrice\": 400,  \"itemsCount\": 3}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c <code>jsonField(\"items[*].price\")<\/code> \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u0432\u0441\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>price<\/code> \u0438\u0437 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 <code>items<\/code> \u0432 \u0435\u0434\u0438\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a <code>[100, 250, 50]<\/code>, \u0430 <code>sum()<\/code> \u0438 <code>count()<\/code> \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0443\u0436\u0435 \u0441 \u044d\u0442\u0438\u043c \u0433\u043e\u0442\u043e\u0432\u044b\u043c \u0441\u043f\u0438\u0441\u043a\u043e\u043c, \u0430 \u043d\u0435 \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c JSON \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e.<\/p>\n<p><a class=\"anchor\" name=\"primer-2-sredniy-chek-s-proverkoy-na-pustoy-zakaz\" id=\"primer-2-sredniy-chek-s-proverkoy-na-pustoy-zakaz\"><\/a><\/p>\n<h3>\u041f\u0440\u0438\u043c\u0435\u0440 2 \u2014 \u0441\u0440\u0435\u0434\u043d\u0438\u0439 \u0447\u0435\u043a \u0441 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439 \u043d\u0430 \u043f\u0443\u0441\u0442\u043e\u0439 \u0437\u0430\u043a\u0430\u0437<\/h3>\n<p>\u042d\u0442\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u043a\u0430\u043a \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0437\u0430\u0449\u0438\u0442\u0443 \u043e\u0442 \u043f\u0443\u0441\u0442\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0447\u0435\u0440\u0435\u0437 <code>if<\/code>, \u043d\u0435 \u0434\u043e\u0436\u0438\u0434\u0430\u044f\u0441\u044c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/__admin\/extensions\/wiremock-js\/scripts \\  --header 'Content-Type: application\/json' \\  --data '{\"name\": \"Average order value\",\"description\": \"\u0421\u0447\u0438\u0442\u0430\u0435\u0442 \u0441\u0440\u0435\u0434\u043d\u0438\u0439 \u0447\u0435\u043a \u043f\u043e \u043f\u043e\u0437\u0438\u0446\u0438\u044f\u043c \u0437\u0430\u043a\u0430\u0437\u0430\",\"sourceCode\": \"var prices = jsonField(\\\"items[*].price\\\"); if (count(prices) == 0) { return { \\\"status\\\": 400, \\\"body\\\": { \\\"error\\\": \\\"order has no items\\\" } }; } var average = avg(prices); return { \\\"status\\\": 200, \\\"body\\\": { \\\"averagePrice\\\": average, \\\"itemsCount\\\": count(prices) } };\"}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/7d9\/ed3\/94c\/7d9ed394cc6e1fb61845b8587b0baedf.png\" alt=\"image-20260802235700141\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/7d9\/ed3\/94c\/7d9ed394cc6e1fb61845b8587b0baedf.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/7d9\/ed3\/94c\/7d9ed394cc6e1fb61845b8587b0baedf.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802235700141<\/figcaption><\/div>\n<\/figure>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/__admin\/mappings \\  --header 'Content-Type: application\/json' \\  --data '{\"request\": {\"method\": \"POST\",\"urlPath\": \"\/api\/orders\/average\"},\"response\": {\"status\": 200,\"transformers\": [\"wiremock-js\"],\"transformerParameters\": {\"scriptId\": \"29e202ac-98e3-4aa4-be0d-16f9d450cf31\"}}}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/df4\/178\/92c\/df417892c9a1504b7f052e248d131268.png\" alt=\"image-20260802235712998\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/df4\/178\/92c\/df417892c9a1504b7f052e248d131268.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/df4\/178\/92c\/df417892c9a1504b7f052e248d131268.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802235712998<\/figcaption><\/div>\n<\/figure>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/api\/orders\/average \\  --header 'Content-Type: application\/json' \\  --data '{\"items\": [{\"price\": 100},{\"price\": 300}]}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/f6a\/f05\/2b5\/f6af052b55ba49b1f477493956670695.png\" alt=\"image-20260802235725129\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/f6a\/f05\/2b5\/f6af052b55ba49b1f477493956670695.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/f6a\/f05\/2b5\/f6af052b55ba49b1f477493956670695.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802235725129<\/figcaption><\/div>\n<\/figure>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<pre><code class=\"bash\">{  \"averagePrice\": 200,  \"itemsCount\": 2}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410 \u043f\u0440\u0438 \u043f\u0443\u0441\u0442\u043e\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u0435 <code>items<\/code>:<\/p>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/api\/orders\/average \\  --header 'Content-Type: application\/json' \\  --data '{\"items\": []}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u2014 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430 400, \u0430 \u043d\u0435 \u043f\u0430\u0434\u0435\u043d\u0438\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u0441 \u043d\u0435\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c:<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/542\/1f8\/d5e\/5421f8d5e8452225f858cd485d531d4e.png\" alt=\"image-20260802235829074\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/542\/1f8\/d5e\/5421f8d5e8452225f858cd485d531d4e.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/542\/1f8\/d5e\/5421f8d5e8452225f858cd485d531d4e.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260802235829074<\/figcaption><\/div>\n<\/figure>\n<pre><code class=\"json\">{  \"error\": \"order has no items\"}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><a class=\"anchor\" name=\"foreach-po-massivu\" id=\"foreach-po-massivu\"><\/a><\/p>\n<h4>ForEach \u043f\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0443<\/h4>\n<p>\u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c <code>visitForEachStatement<\/code> \u2014 \u0446\u0438\u043a\u043b <code>forEach<\/code> \u043f\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0443. \u041f\u043e\u0447\u0435\u043c\u0443 \u0438\u043c\u0435\u043d\u043d\u043e <code>forEach<\/code>, \u0430 \u043d\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0439 <code>while<\/code>\/<code>for<\/code> \u0441 \u0443\u0441\u043b\u043e\u0432\u0438\u0435\u043c:<\/p>\n<p><code><strong>forEach<\/strong><\/code><strong> \u043f\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0443<\/strong> \u2014 \u0447\u0438\u0441\u043b\u043e \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439 \u0436\u0451\u0441\u0442\u043a\u043e \u0440\u0430\u0432\u043d\u043e <code>itemsList.size()<\/code>, \u0442\u043e \u0435\u0441\u0442\u044c \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u0439, \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u0435 \u0441\u043f\u0438\u0441\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0430 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c \u0442\u0435\u043b\u0430 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u0430. \u0411\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 <code>forEach<\/code> \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u0435\u043d \u2014 \u043c\u0430\u0441\u0441\u0438\u0432 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0441\u0442\u0430\u0442\u044c \u0434\u043b\u0438\u043d\u043d\u0435\u0435 \u0441\u0430\u043c\u043e\u0433\u043e JSON, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u0441\u043b\u0430\u043b \u043a\u043b\u0438\u0435\u043d\u0442.<\/p>\n<p><strong>\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0439 <\/strong><code><strong>while (condition)<\/strong><\/code><strong> \u0438\u043b\u0438 <\/strong><code><strong>for (init; condition; step)<\/strong><\/code> \u2014 \u0447\u0438\u0441\u043b\u043e \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f <code>condition<\/code> \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u043c \u0448\u0430\u0433\u0435, \u0430 \u044d\u0442\u043e \u0443\u0436\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0441\u043a\u0440\u0438\u043f\u0442\u0430. \u041e\u0448\u0438\u0431\u043a\u0430 \u0432 \u0443\u0441\u043b\u043e\u0432\u0438\u0438 (\u0437\u0430\u0431\u044b\u043b\u0438 <code>i++<\/code>, \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0441\u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0432\u044b\u0445\u043e\u0434) \u2014 \u0438 \u0446\u0438\u043a\u043b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432\u0435\u0447\u043d\u043e, \u0441\u044a\u0435\u0434\u0430\u044f CPU \u043f\u043e\u0442\u043e\u043a\u0430 \u0432 <code>CompletableFuture.supplyAsync<\/code>, \u043f\u043e\u043a\u0430 \u0442\u0430\u0439\u043c\u0430\u0443\u0442 <code>EXECUTION_TIMEOUT_MS<\/code> \u043d\u0435 \u043f\u0440\u0435\u0440\u0432\u0451\u0442 <code>Future<\/code> \u2014 \u043d\u043e \u0441\u0430\u043c \u043f\u043e\u0442\u043e\u043a \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043c\u0433\u043d\u043e\u0432\u0435\u043d\u043d\u043e.<\/p>\n<p><a class=\"anchor\" name=\"gde-togda-mesto-sum-count-avg-ryadom-s-foreach\" id=\"gde-togda-mesto-sum-count-avg-ryadom-s-foreach\"><\/a><\/p>\n<h4>\u0413\u0434\u0435 \u0442\u043e\u0433\u0434\u0430 \u043c\u0435\u0441\u0442\u043e sum\/count\/avg \u0440\u044f\u0434\u043e\u043c \u0441 forEach<\/h4>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 <code>sum()<\/code>, <code>count()<\/code>, <code>avg()<\/code> \u043f\u043e \u0441\u0443\u0442\u0438 \u0434\u0435\u043b\u0430\u044e\u0442 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 <code>forEach<\/code> \u0432\u0440\u0443\u0447\u043d\u0443\u044e:<\/p>\n<pre><code>var total = 0;for (var item of items) {    total = total + item.price;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u043e <code>sum(jsonField(\"items.price\"))<\/code> \u043a\u043e\u0440\u043e\u0447\u0435 \u0438 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u0438\u0441\u0430\u0442\u044c \u0434\u0430\u0436\u0435 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0439 <code>forEach<\/code> \u0434\u043b\u044f \u0442\u0438\u043f\u043e\u0432\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u2014 \u0430\u0433\u0440\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u2014 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u044b\u0439, \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0448\u043e\u0440\u0442\u043a\u0430\u0442 \u043d\u0430\u0434 \u0442\u043e\u0439 \u0436\u0435 \u0441\u0430\u043c\u043e\u0439 \u0438\u0434\u0435\u0435\u0439 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438, \u0430 \u043d\u0435 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u0430\u044f \u0431\u043e\u043b\u0435\u0435 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0430\u044f \u0437\u0430\u043c\u0435\u043d\u0430 \u0446\u0438\u043a\u043b\u0430\u043c, \u043a\u0430\u043a \u044f \u0441\u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043b \u0440\u0430\u043d\u0435\u0435. <code>forEach<\/code> \u0438 <code>sum\/count\/avg<\/code> \u0440\u0435\u0448\u0430\u044e\u0442 \u043e\u0434\u043d\u0443 \u0438 \u0442\u0443 \u0436\u0435 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044e \u0437\u0430\u0434\u0430\u0447 (\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043c\u0430\u0441\u0441\u0438\u0432\u0430), \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u0443\u0440\u043e\u0432\u043d\u044f\u0445 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438 \u2014 <code>forEach<\/code> \u0434\u0430\u0451\u0442 \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u044c \u0434\u043b\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0435, \u0430 \u0430\u0433\u0440\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u2014 \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u043f\u0443\u0442\u044c \u0434\u043b\u044f \u0441\u0430\u043c\u044b\u0445 \u0447\u0430\u0441\u0442\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0431\u0435\u0437 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0446\u0438\u043a\u043b\u0430 \u0432\u0440\u0443\u0447\u043d\u0443\u044e.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 1 \u2014 \u0441\u043a\u0438\u0434\u043a\u0430 \u043d\u0430 \u0442\u043e\u0432\u0430\u0440\u044b:<\/p>\n<p>\u0414\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u0434\u0432\u0430 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u0434\u0435\u043b\u0430\u044e\u0449\u0438\u0445 \u043e\u0434\u043d\u043e \u0438 \u0442\u043e\u0436\u0435. \u041e\u0434\u043d\u043e \u0441 forEach, \u0430 \u0432\u0442\u043e\u0440\u043e\u0435 \u0441 \u0430\u0433\u0440\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438<\/p>\n<pre><code class=\"javascript\">var items = jsonField(\"items\");var total = 0;for (var item of items) {    var discountedPrice = item.price * 0.9;    var total = total + discountedPrice;}return {    \"status\": 200,    \"body\": {        \"originalItemsCount\": count(items),        \"totalAfterDiscount\": total    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code class=\"javascript\">var prices = jsonField(\"items[*].price\");var total = sum(prices) * 0.9;return {    \"status\": 200,    \"body\": {        \"originalItemsCount\": count(prices),        \"totalAfterDiscount\": total    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/__admin\/extensions\/wiremock-js\/scripts \\  --header 'Content-Type: application\/json' \\  --data '{\"name\": \"Apply discount to order items\",\"sourceCode\": \"var items = jsonField(\\\"items\\\"); var total = 0; for (var item of items) { var discountedPrice = item.price * 0.9; var total = total + discountedPrice; } return { \\\"status\\\": 200, \\\"body\\\": { \\\"originalItemsCount\\\": count(items), \\\"totalAfterDiscount\\\": total } };\"}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/311\/8f8\/0c3\/3118f80c34f4dc6704c19c4550c47277.png\" alt=\"image-20260803000728764\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/311\/8f8\/0c3\/3118f80c34f4dc6704c19c4550c47277.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/311\/8f8\/0c3\/3118f80c34f4dc6704c19c4550c47277.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260803000728764<\/figcaption><\/div>\n<\/figure>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/__admin\/mappings \\  --header 'Content-Type: application\/json' \\  --data '{\"request\": {\"method\": \"POST\",\"urlPath\": \"\/api\/orders\/discount\"},\"response\": {\"status\": 200,\"transformers\": [\"wiremock-js\"],\"transformerParameters\": {\"scriptId\": \"62daaa03-d7fc-4c3b-b117-fd99086c788d\"}}}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/d43\/d88\/85e\/d43d8885e71125cece7004d48a0efb75.png\" alt=\"image-20260803000821075\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/d43\/d88\/85e\/d43d8885e71125cece7004d48a0efb75.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/d43\/d88\/85e\/d43d8885e71125cece7004d48a0efb75.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260803000821075<\/figcaption><\/div>\n<\/figure>\n<pre><code class=\"bash\">curl --request POST \\  --url http:\/\/localhost:8888\/api\/orders\/discount \\  --header 'Content-Type: application\/json' \\  --data '{\"items\": [{\"name\": \"Book\",\"price\": 100},{\"name\": \"Pen\",\"price\": 50},{\"name\": \"Notebook\",\"price\": 200}]}'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/665\/7d1\/85c\/6657d185c66007b3fbe98e5369d94f0f.png\" alt=\"image-20260803000856549\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/665\/7d1\/85c\/6657d185c66007b3fbe98e5369d94f0f.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/665\/7d1\/85c\/6657d185c66007b3fbe98e5369d94f0f.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>image-20260803000856549<\/figcaption><\/div>\n<\/figure>\n<p><a class=\"anchor\" name=\"limity\" id=\"limity\"><\/a><\/p>\n<h3>\u041b\u0438\u043c\u0438\u0442\u044b<\/h3>\n<p>\u041f\u043e\u0447\u0435\u043c\u0443 \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a\u0438\u0435 \u043b\u0438\u043c\u0438\u0442\u044b? \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f 2000 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0438 5 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u2014 \u043d\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0435 \u0446\u0438\u0444\u0440\u044b, \u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0440\u0430\u0441\u0447\u0451\u0442\u0430: \u043f\u0440\u0438 \u043b\u0438\u043c\u0438\u0442\u0435 \u0432 2000 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 ~220 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 (<code>var x = ...;<\/code> \u2014 \u043c\u0438\u043d\u0438\u043c\u0443\u043c 9 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u043d\u0430 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435), \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 <code>MAX_VARIABLES<\/code> \u043d\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0437\u0430\u0449\u0438\u0442\u044b \u2014 \u043b\u0438\u043c\u0438\u0442 \u0434\u043b\u0438\u043d\u044b \u0443\u0436\u0435 \u0440\u0435\u0448\u0430\u0435\u0442 \u044d\u0442\u0443 \u0437\u0430\u0434\u0430\u0447\u0443. \u041f\u043e\u0445\u043e\u0436\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0441\u0442\u043e\u0438\u0442 \u0437\u0430 \u043e\u0442\u043a\u0430\u0437\u043e\u043c \u043e\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u0447\u0451\u0442\u0447\u0438\u043a\u0430 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439 \u0446\u0438\u043a\u043b\u0430 (\u043a\u0430\u043a \u0432 <code>MAX_LOOP_ITERATIONS<\/code> \u0443 Salesforce Apex) \u2014 <code>forEach<\/code> \u0432 WiremockJs \u0438\u0442\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0441\u0442\u0440\u043e\u0433\u043e \u043f\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0443 \u0443\u0436\u0435 \u0433\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430, \u0438 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0451\u043d \u0441\u0430\u043c\u043e\u0439 \u043f\u0440\u0438\u0440\u043e\u0434\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438, \u0430 \u043d\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u043b\u0438\u043c\u0438\u0442\u043e\u043c \u0441\u0432\u0435\u0440\u0445\u0443.<\/p>\n<p>\u0412\u043e\u0442 \u0441\u0432\u043e\u0434\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439 WiremockJs<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0413\u0434\u0435 \u0437\u0430\u0434\u0430\u0451\u0442\u0441\u044f<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u043e\u0447\u0435\u043c\u0443 \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0434\u043b\u0438\u043d\u0430 \u0441\u043a\u0440\u0438\u043f\u0442\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">2000 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>ScriptGuard.maxScriptLength<\/code> (system property <code>wiremockjs.max.script.length<\/code>)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0440\u0438 \u0442\u0430\u043a\u043e\u0439 \u0434\u043b\u0438\u043d\u0435 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435\u043b\u044c\u0437\u044f \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 ~220 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 MAX_VARIABLES \u043d\u0435 \u043d\u0443\u0436\u0435\u043d<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0433\u043b\u0443\u0431\u0438\u043d\u0430 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0431\u043b\u043e\u043a\u043e\u0432<\/p>\n<\/td>\n<td>\n<p align=\"left\">5 \u0443\u0440\u043e\u0432\u043d\u0435\u0439<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>ScriptGuard.MAX_NESTING_DEPTH<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0417\u0430\u0449\u0438\u0442\u0430 \u043e\u0442 \u0438\u0441\u043a\u0443\u0441\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0440\u0430\u0437\u0434\u0443\u0442\u044b\u0445 \u0434\u0435\u0440\u0435\u0432\u044c\u0435\u0432 \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u0431\u0435\u0437 \u043b\u0438\u0448\u043d\u0435\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u0430\u0440\u0441\u0435\u0440\u0430<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0422\u0430\u0439\u043c\u0430\u0443\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u043a\u0440\u0438\u043f\u0442\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">100 \u043c\u0441<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>ScriptTransformer.EXECUTION_TIMEOUT_MS<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u0430\u0436\u0435 \u0441 \u0445\u043e\u043b\u043e\u0434\u043d\u044b\u043c \u0441\u0442\u0430\u0440\u0442\u043e\u043c Faker \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0433\u0440\u0435\u0432\u0430, \u043d\u043e \u0436\u0451\u0441\u0442\u043a\u043e \u0440\u0435\u0436\u0435\u0442 \u0437\u0430\u0432\u0438\u0441\u0448\u0438\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u044b<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0426\u0438\u043a\u043b\u044b \u0441 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u043c \u0443\u0441\u043b\u043e\u0432\u0438\u0435\u043c<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 (\u043d\u0435\u0442 while, for \u0441 \u0443\u0441\u043b\u043e\u0432\u0438\u0435\u043c)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0413\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0430 (\u0442\u043e\u043b\u044c\u043a\u043e <code>forEachStatement<\/code>)<\/p>\n<\/td>\n<td>\n<p align=\"left\">forEach \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c \u0433\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u2014 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0451\u043d, \u0430 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043f\u0440\u0435\u0449\u0451\u043d \u043b\u0438\u043c\u0438\u0442\u043e\u043c<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0421\u0447\u0451\u0442\u0447\u0438\u043a \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439 \u0446\u0438\u043a\u043b\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0435 \u043d\u0443\u0436\u0435\u043d (\u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 MAX_LOOP_ITERATIONS \u0432 Salesforce Apex)<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u2014<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0427\u0438\u0441\u043b\u043e \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439 forEach \u0440\u0430\u0432\u043d\u043e <code>itemsList.size()<\/code>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0435\u0432\u044b\u0448\u0430\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0440 \u0442\u0435\u043b\u0430 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \/ eval<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442<\/p>\n<\/td>\n<td>\n<p align=\"left\">Whitelist \u0432 <code>callWhitelistedFunction<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0422\u043e\u043b\u044c\u043a\u043e \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u2014 \u043d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043d\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043c\u0430\u0441\u0441\u0438\u0432\u0430<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0420\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u044b\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0422\u043e\u043b\u044c\u043a\u043e RE2J, \u0431\u0435\u0437 backreferences \u0438 \u0447\u0430\u0441\u0442\u0438 lookahead\/lookbehind<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>matches()<\/code> \u0447\u0435\u0440\u0435\u0437 <code>com.google.re2j.Pattern<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0413\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f O(n), \u0438\u0441\u043a\u043b\u044e\u0447\u0430\u0435\u0442 ReDoS \u0447\u0435\u0440\u0435\u0437 catastrophic backtracking<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043b\u044e\u0447\u0435\u0439<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0422\u043e\u043b\u044c\u043a\u043e \u043f\u043e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c\u0443 \u0441\u043b\u043e\u0432\u0430\u0440\u044e (<code>mapKeys<\/code>), \u0431\u0435\u0437 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c\u044b\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u043d\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>mapKeys(array, mapping)<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 map(item =&gt; \u2026) \u043e\u0437\u043d\u0430\u0447\u0430\u043b\u0430 \u0431\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 eval-\u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0438 \u0432 \u044f\u0437\u044b\u043a<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0414\u043e\u0441\u0442\u0443\u043f \u043a \u0437\u0430\u043f\u0440\u043e\u0441\u0443<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0422\u043e\u043b\u044c\u043a\u043e \u0447\u0435\u0440\u0435\u0437 <code>RequestFacade<\/code>, \u0431\u0435\u0437 \u043f\u0440\u044f\u043c\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 Request<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>visitFieldAccessExpr<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">request.method \u0438 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0436\u0451\u0441\u0442\u043a\u043e \u0431\u0440\u043e\u0441\u0430\u044e\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><a class=\"anchor\" name=\"hronologiya-problem\" id=\"hronologiya-problem\"><\/a><\/p>\n<h3>\u0425\u0440\u043e\u043d\u043e\u043b\u043e\u0433\u0438\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c<\/h3>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0440\u0438\u0447\u0438\u043d\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0420\u0435\u0448\u0435\u043d\u0438\u0435<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>UnsupportedClassVersionError<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">DataFaker 2.7.0 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d \u043f\u043e\u0434 Java 17+, \u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 WireMock \u2014 Java 11<\/p>\n<\/td>\n<td>\n<p align=\"left\">Downgrade \u043d\u0430 <code>datafaker:1.9.0<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0422\u0430\u0439\u043c\u0430\u0443\u0442 100 \u043c\u0441 \u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u0432\u044b\u0437\u043e\u0432\u0435 <code>fake()<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0425\u043e\u043b\u043e\u0434\u043d\u0430\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 YAML-\u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u043e\u0432 <code>Faker<\/code> \u043f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>FakerHolder<\/code> \u2014 \u0441\u0438\u043d\u0433\u043b\u0442\u043e\u043d, \u043f\u0440\u043e\u0433\u0440\u0435\u0442\u044b\u0439 \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 <code>ScriptTransformer<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0422\u0430\u0439\u043c\u0430\u0443\u0442 100 \u043c\u0441 \u0434\u0430\u0436\u0435 \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0433\u0440\u0435\u0432\u0430 <code>Faker<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0445\u043e\u043b\u043e\u0434\u043d\u044b\u0439 \u0441\u0442\u0430\u0440\u0442 \u0434\u0432\u0438\u0436\u043a\u0430 <code>expression()<\/code> \u2014 \u0434\u0440\u0443\u0433\u0430\u044f \u043f\u043e\u0434\u0441\u0438\u0441\u0442\u0435\u043c\u0430 DataFaker<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0440\u043e\u0433\u0440\u0435\u0432\u043e\u0447\u043d\u044b\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u0430\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>fake(...)<\/code>, \u0430 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0451\u0442 <code>Faker<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>missing '=' at 'fake'<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041e\u0448\u0438\u0431\u043a\u0430 \u0440\u0443\u0447\u043d\u043e\u0433\u043e \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u043f\u043e\u0441\u043b\u0435 \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0433\u043e \u0438\u043c\u043f\u043e\u0440\u0442\u0430 \u0432 Insomnia<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 <code>sourceCode<\/code> \u0447\u0435\u0440\u0435\u0437 Admin API \u043f\u0435\u0440\u0435\u0434 \u0432\u044b\u0437\u043e\u0432\u043e\u043c \u0441\u0442\u0430\u0431\u0430<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><code>fake()<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u043b \u0442\u0435\u043a\u0441\u0442 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u043a\u0430\u043a \u0435\u0441\u0442\u044c<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 DataFaker <code>expression()<\/code> \u0442\u0440\u0435\u0431\u0443\u0435\u0442 <code>#{...}<\/code>, \u0430 \u043d\u0435 \u0433\u043e\u043b\u043e\u0435 \u0438\u043c\u044f \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u0438\u043c\u0435\u043d\u0430 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u043e\u0432 \u0432 <code>#{Category.method}<\/code><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p><a class=\"anchor\" name=\"zapustk-wiremock-s-rasshireniem\" id=\"zapustk-wiremock-s-rasshireniem\"><\/a><\/p>\n<h3>\u0417\u0430\u043f\u0443\u0441\u043a Wiremock \u0441 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435\u043c<\/h3>\n<p>\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c Wiremock \u0441 \u0440\u0430\u0448\u0438\u0440\u0435\u043d\u0438\u0435\u043c \u043c\u043e\u0436\u043d\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e docker-compose.yml<\/p>\n<pre><code class=\"yaml\">services:  wiremock:    image: wiremock\/wiremock:3.13.1    container_name: wiremock-server    ports:      - \"8888:8080\"    volumes:      - .\/wiremock\/mappings:\/home\/wiremock\/mappings      - .\/wiremock\/files:\/home\/wiremock\/__files      - .\/wiremock\/extensions\/wiremock-js-extension.jar:\/var\/wiremock\/extensions\/wiremock-js-extension.jar      - .\/wiremock\/scripts:\/home\/wiremock\/scripts    environment:      - WIREMOCKJS_STORAGE_DIR=\/home\/wiremock\/scripts    command:      - \"--port=8080\"      - \"--verbose\"      - \"--local-response-templating\"      - \"--extensions=ru.mcs.wiremockjs.ScriptTransformer,ru.mcs.wiremockjs.admin.ScriptAdminApi\"<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><a class=\"anchor\" name=\"zaklyuchenie\" id=\"zaklyuchenie\"><\/a><\/p>\n<h3>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h3>\n<p>\u042d\u0442\u043e \u0431\u044b\u043b\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435 \u043f\u0440\u0438\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0435\u0447\u0435\u0440\u043e\u0432. \u0410 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043d\u0435 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443. \u0415\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u043e\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0435\u0449\u0435 \u043a\u043e\u043c\u0443-\u0442\u043e \u0442\u043e \u044f \u0431\u0443\u0434\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0434.<\/p>\n<p><a class=\"anchor\" name=\"ssylki\" id=\"ssylki\"><\/a><\/p>\n<h3>\u0421\u0441\u044b\u043b\u043a\u0438<\/h3>\n<ol>\n<li>\n<p><a href=\"https:\/\/github.com\/malexple\/wiremock-js-extension\" rel=\"noopener noreferrer nofollow\">wiremock-js-extension<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/malexple\/web-wiremock\" rel=\"noopener noreferrer nofollow\">web-wiremock<\/a><\/p>\n<\/li>\n<\/ol>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1066180\/\">https:\/\/habr.com\/ru\/articles\/1066180\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u044b\u0439 \u044f\u0437\u044b\u043a WiremockJs \u2014 \u0441 \u043d\u0443\u043b\u044f \u0438 \u0434\u043e \u0440\u0430\u0431\u043e\u0447\u0435\u0433\u043e \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u0430. \u041f\u043e\u0434\u0435\u043b\u044e\u0441\u044c, \u0447\u0442\u043e \u043c\u0435\u043d\u044f \u043f\u043e\u0434\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u043e \u043a \u044d\u0442\u043e\u043c\u0443 \u00ab\u043f\u043e\u0434\u0432\u0438\u0433\u0443\u00bb, \u043a\u0430\u043a \u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043b \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0443, \u0441 \u043a\u0430\u043a\u0438\u043c\u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f\u043c\u0438 \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f \u0438 \u043f\u043e\u0447\u0435\u043c\u0443 \u0432 \u0438\u0442\u043e\u0433\u0435 \u043d\u0435 \u0441\u0442\u0430\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c JavaScript, \u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u0441\u0432\u043e\u0439 \u0443\u043f\u0440\u043e\u0449\u0451\u043d\u043d\u044b\u0439 \u0434\u0438\u0430\u043b\u0435\u043a\u0442. \u041f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c \u2014 ANTLR, \u043f\u0430\u0440\u0441\u0435\u0440\u044b, \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0431\u043e\u043b\u0438 \u0438 \u043c\u043d\u043e\u0433\u043e \u0443\u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u0438\u044f \u043e\u0442 \u0442\u0432\u043e\u0440\u0447\u0435\u0441\u0442\u0432\u0430.\u041e\u0433\u043b\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u041f\u0440\u0435\u0434\u0438\u0441\u043b\u043e\u0432\u0438\u0435: \u043a\u0430\u043a \u0432\u0441\u0451 \u043d\u0430\u0447\u0438\u043d\u0430\u043b\u043e\u0441\u044c\u041d\u0430 \u0447\u0451\u043c \u044f \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0441\u044f \u0432 \u043f\u0440\u043e\u0448\u043b\u044b\u0439 \u0440\u0430\u0437? \u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a \u0431\u044b\u043b\u043e \u0438 \u0441\u0442\u0430\u043b\u043e\u0413\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u041b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0442\u043e\u043a\u0435\u043d\u044bVisitor: \u043a\u0430\u043a \u0434\u0435\u0440\u0435\u0432\u043e \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u041a\u0430\u043a WireMock \u0443\u0437\u043d\u0430\u0451\u0442 \u043f\u0440\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435? \u0422\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430: transform()\u0417\u0430\u0449\u0438\u0442\u0430 \u043e\u0442 \u0437\u0430\u0432\u0438\u0441\u0430\u043d\u0438\u0439: \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f\u0417\u0430\u0447\u0435\u043c \u043d\u0443\u0436\u0435\u043d RequestFacade?ScriptGuard: \u043f\u0435\u0440\u0432\u0430\u044f \u043b\u0438\u043d\u0438\u044f \u0437\u0430\u0449\u0438\u0442\u044b \u0434\u043e ANTLR \u0414\u0432\u0430 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0432\u044b\u0437\u043e\u0432\u0430 \u2014 \u043d\u0430 \u0432\u0445\u043e\u0434\u0435 \u0438 \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438\u0410\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430\u043c\u0438 \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432:\u0424\u0443\u043d\u043a\u0446\u0438\u0438 jsonField(path)\u0414\u0430\u0442\u044b \u0447\u0435\u0440\u0435\u0437 java.time, \u0430 \u043d\u0435 \u0432\u0440\u0443\u0447\u043d\u0443\u044euuid() \u0438 randomInt() \u2014 \u0441 \u043e\u0433\u043b\u044f\u0434\u043a\u043e\u0439 \u043d\u0430 \u0434\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0438\u0437\u043c \u0417\u0430\u0447\u0435\u043c seed \u043d\u0443\u0436\u0435\u043d \u0438\u043c\u0435\u043d\u043d\u043e \u0432 WiremockJs\u0428\u0430\u0433 1 \u2014 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u043a\u0440\u0438\u043f\u0442 \u0441 seed\u0428\u0430\u0433 2 \u2014 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u0442\u0430\u0431, \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0439 \u043a \u0441\u043a\u0440\u0438\u043f\u0442\u0443\u0428\u0430\u0433 3 \u2014 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0441\u0442\u0430\u0431 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u041a\u0430\u043a \u044d\u0442\u043e \u0432\u0435\u0434\u0451\u0442 \u0441\u0435\u0431\u044f \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435matches(str, pattern) \u041f\u0440\u0438\u043c\u0435\u0440 1 \u2014 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u0444\u043e\u0440\u043c\u0430\u0442\u0430 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430 \u043f\u0435\u0440\u0435\u0434 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 \u0437\u0430\u043a\u0430\u0437\u0430\u041f\u0440\u0438\u043c\u0435\u0440 2 &#8212; \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0430\u043c \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430\u0417\u0430\u0447\u0435\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u043b\u0441\u044f RE2Jfake() \u2014 \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0430 \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0441\u0442\u0438\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u041f\u0440\u0438\u043c\u0435\u0440 1 \u2014 \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u041f\u0440\u0438\u043c\u0435\u0440 2 \u2014 \u0434\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0444\u0435\u0439\u043a\u043e\u0432\u044b\u0439 \u0437\u0430\u043a\u0430\u0437 \u0447\u0435\u0440\u0435\u0437 seed\u041f\u0440\u0438\u043c\u0435\u0440 3 \u2014 \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0435 fake() \u0441 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438\u0437 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u041f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u044b DataFaker \u0434\u043b\u044f \u0441\u043f\u0440\u0430\u0432\u043a\u0438\u041a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0432 \u043e\u0434\u043d\u043e\u043c \u0432\u044b\u0437\u043e\u0432\u0435mapKeys() \u2014 \u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u0435\u0439 \u0431\u0435\u0437 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0433\u043e eval\u0410\u0433\u0440\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u041f\u043e\u0447\u0435\u043c\u0443 \u0430\u0433\u0440\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438\u041a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c\u041f\u0440\u0438\u043c\u0435\u0440 1 \u2014 \u0441\u0443\u043c\u043c\u0430 \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0442\u043e\u0432\u0430\u0440\u043e\u0432 \u0432 \u0437\u0430\u043a\u0430\u0437\u0435\u041f\u0440\u0438\u043c\u0435\u0440 2 \u2014 \u0441\u0440\u0435\u0434\u043d\u0438\u0439 \u0447\u0435\u043a \u0441 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439 \u043d\u0430 \u043f\u0443\u0441\u0442\u043e\u0439 \u0437\u0430\u043a\u0430\u0437ForEach \u043f\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0443\u0413\u0434\u0435 \u0442\u043e\u0433\u0434\u0430 \u043c\u0435\u0441\u0442\u043e sum\/count\/avg \u0440\u044f\u0434\u043e\u043c \u0441 forEach\u041b\u0438\u043c\u0438\u0442\u044b\u0425\u0440\u043e\u043d\u043e\u043b\u043e\u0433\u0438\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0417\u0430\u043f\u0443\u0441\u0442\u043a Wiremock \u0441 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435\u043c\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u0421\u0441\u044b\u043b\u043a\u0438\u041f\u0440\u0435\u0434\u0438\u0441\u043b\u043e\u0432\u0438\u0435. \u041a\u0430\u043a \u0432\u0441\u0451 \u043d\u0430\u0447\u0438\u043d\u0430\u043b\u043e\u0441\u044c\u041f\u0430\u0440\u0443 \u043c\u0435\u0441\u044f\u0446\u0435\u0432 \u043d\u0430\u0437\u0430\u0434 \u044f \u0441\u0434\u0435\u043b\u0430\u043b UI \u0434\u043b\u044f WireMock. \u0412 \u043d\u0435\u0433\u043e \u0432\u043e\u0448\u043b\u043e \u0432\u0441\u0451, \u0447\u0442\u043e \u044f \u0442\u043e\u0433\u0434\u0430 \u0443\u0441\u043f\u0435\u043b:\u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0441\u0442\u0430\u0431\u043e\u0432,\u0443\u0434\u043e\u0431\u043d\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e API \u0441 \u043f\u043e\u0438\u0441\u043a\u043e\u043c \u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0435\u0439,\u0432\u044b\u0437\u043e\u0432 \u0441\u0442\u0430\u0431\u0430 \u043f\u0440\u044f\u043c\u043e \u0438\u0437 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 (\u0431\u0435\u0437 Postman),\u0438\u0441\u0442\u043e\u0440\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0432\u043a\u043b\u0430\u0434\u043a\u0435,\u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u043c\u043e\u043a\u043e\u0432.\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u0431\u043e\u0432 \u043f\u043e openApi \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438\u041d\u043e \u0433\u043b\u0430\u0432\u043d\u043e\u0435, \u0447\u0442\u043e \u0438\u0437\u0431\u0430\u0432\u0438\u043b\u043e \u043c\u0435\u043d\u044f \u043e\u0442 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0439 \u0433\u043e\u043b\u043e\u0432\u043d\u043e\u0439 \u0431\u043e\u043b\u0438 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u043c\u0435\u0436\u0434\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u043c\u0438, \u2014 \u043f\u0440\u043e\u0444\u0438\u043b\u0438. \u0417\u0430\u0433\u0440\u0443\u0437\u0438\u043b \u043d\u0443\u0436\u043d\u044b\u0439 \u043f\u0440\u043e\u0444\u0438\u043b\u044c \u2014 \u0438 \u0432\u0441\u0435 \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0438 \u0443\u0436\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u044b, \u043d\u0435 \u043d\u0430\u0434\u043e \u0434\u0443\u043c\u0430\u0442\u044c \u043e \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0430\u0445 \u0438 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f\u0445 \u0440\u0443\u0447\u0435\u043a. \u041a\u0441\u0442\u0430\u0442\u0438, \u043c\u043d\u043e\u0433\u0438\u0435 UI \u043f\u044b\u0442\u0430\u044e\u0442\u0441\u044f \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043f\u043e\u043a\u0430\u0437 API \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043c\u043e\u043a\u043e\u0432 \u0432 \u043f\u0430\u043f\u043a\u0430\u0445, \u043a\u0430\u043a \u0432 Postman, \u043d\u043e \u044f \u0441\u0447\u0438\u0442\u0430\u044e \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0443\u0434\u043e\u0431\u043d\u044b\u043c. \u041f\u0440\u043e\u0444\u0438\u043b\u0438 \u043e\u043a\u0430\u0437\u0430\u043b\u0438\u0441\u044c \u043f\u0440\u043e\u0449\u0435 \u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u043d\u0435\u0435.\u0412\u0442\u043e\u0440\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u2013 \u044d\u0442\u043e \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432. \u0411\u044b\u043b\u043e \u043d\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0430 \u0432\u044b\u0437\u0432\u0430\u043b\u0441\u044f \u043b\u0438 \u0437\u0430\u043f\u0440\u043e\u0441? \u0410 \u0447\u0442\u043e \u043f\u0440\u0438\u0448\u043b\u043e \u0438 \u043a\u043e\u0433\u0434\u0430?\u0422\u0440\u0435\u0442\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0438 \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435 \u0441\u0430\u043c\u043e\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u044d\u0442\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0438. \u041f\u043e\u0447\u0435\u043c\u0443-\u0442\u043e \u0441 \u0432\u043e\u043f\u0440\u043e\u0441\u0430\u043c\u0438 \u043f\u043e \u043c\u043e\u043a\u0430\u043c \u043e\u043d\u0438 \u0448\u043b\u0438 \u0438\u043c\u0435\u043d\u043d\u043e \u043a\u043e \u043c\u043d\u0435. \u041f\u043e\u0441\u043b\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0434\u043d\u0435\u0439 \u043a\u043e\u043b\u043b\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u044f \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u0442\u0430\u043a \u0434\u0430\u043b\u044c\u0448\u0435 \u043d\u0435\u043b\u044c\u0437\u044f. \u0412\u043e\u2011\u043f\u0435\u0440\u0432\u044b\u0445, \u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, \u0430 \u043d\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0449\u0438\u043a. \u0412\u043e\u2011\u0432\u0442\u043e\u0440\u044b\u0445, \u044f \u043d\u0435 \u043c\u043e\u0433\u0443 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e \u043e\u0431\u0443\u0447\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0445 \u0441\u043e\u0442\u0440\u0443\u0434\u043d\u0438\u043a\u043e\u0432 \u043d\u044e\u0430\u043d\u0441\u0430\u043c WireMock, MockServer \u0438 JSON. \u041b\u044e\u0434\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0438 \u0443\u0445\u043e\u0434\u044f\u0442, \u0430 \u0432\u0440\u0435\u043c\u044f \u043d\u0430 \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u044f \u0443\u0445\u043e\u0434\u0438\u0442 \u043a\u043e\u043b\u043e\u0441\u0441\u0430\u043b\u044c\u043d\u043e\u0435. \u041f\u043b\u044e\u0441 \u044f \u0441\u0430\u043c \u0437\u0430\u0431\u044b\u0432\u0430\u044e \u0447\u0442\u043e \u044f \u0442\u0430\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b \u0438 \u043a\u0430\u043a \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u043b. \u041c\u043d\u0435 \u043d\u0435\u0445\u0432\u0430\u0442\u0430\u043b\u043e \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430. \u041f\u0440\u043e\u0448\u0435\u043b\u0441\u044f \u043f\u043e \u0448\u0430\u0433\u0430\u043c \u0438 \u0432\u0441\u0435 \u0433\u043e\u0442\u043e\u0432\u043e. \u041d\u0435 \u043d\u0430\u0434\u043e \u0434\u0443\u043c\u0430\u0442\u044c, \u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043b\u0438 \u0442\u044b \u0441\u043e\u0437\u0434\u0430\u043b json.\u0412\u044b \u0441\u043f\u0440\u043e\u0441\u0438\u0442\u0435: \u043f\u043e\u0447\u0435\u043c\u0443 \u043d\u0435 \u0432\u0437\u044f\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f WireMock? \u0422\u0443\u0442 \u043f\u0440\u0438\u0447\u0438\u043d\u0430 \u0432\u043e \u043c\u043d\u0435, \u043c\u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u043a\u043e\u043f\u0430\u0442\u044c\u0441\u044f \u0438 \u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0441\u0451 \u043f\u043e\u0434 \u0441\u0435\u0431\u044f, \u0442\u0430\u043a, \u043a\u0430\u043a \u044f \u0441\u0447\u0438\u0442\u0430\u044e \u0443\u0434\u043e\u0431\u043d\u044b\u043c. \u041d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u0438\u0434\u0438\u0440\u0447\u0438\u0432 \u043a \u0447\u0443\u0436\u0438\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u043c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438 \u0440\u0435\u0448\u0438\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0451.\u0426\u0435\u043d\u0438\u0442 \u043b\u0438 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f \u043c\u0435\u043d\u044f \u0437\u0430 \u0442\u043e, \u0447\u0442\u043e \u044f \u043f\u044b\u0442\u0430\u044e\u0441\u044c \u043f\u0440\u0438\u0432\u043d\u0435\u0441\u0442\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044e \u0438 \u0447\u0442\u043e-\u0442\u043e \u043d\u043e\u0432\u043e\u0435? \u0415\u0441\u043b\u0438 \u0447\u0435\u0441\u0442\u043d\u043e, \u044f \u0443\u0436\u0435 \u0434\u0430\u0432\u043d\u043e \u043d\u0435 \u0437\u0430\u0434\u0430\u044e \u0441\u0435\u0431\u0435 \u044d\u0442\u043e\u0442 \u0432\u043e\u043f\u0440\u043e\u0441. \u042f \u0443\u0436\u0435 \u043f\u0438\u0441\u0430\u043b \u043e\u0431 \u044d\u0442\u043e\u043c \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 (\u0441\u0441\u044b\u043b\u043a\u0430), \u0438 \u043c\u043e\u0439 \u043e\u043f\u044b\u0442 \u0437\u0430 15 \u043b\u0435\u0442 \u0433\u043e\u0432\u043e\u0440\u0438\u0442: \u043d\u0435 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u043b\u044e\u0434\u0438 \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0435\u0451. \u0415\u0441\u043b\u0438 \u043c\u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442 \u0432\u0440\u0435\u043c\u044f, \u044f \u0435\u0433\u043e \u043f\u0438\u043b\u044e. \u0415\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u044b \u0434\u0435\u043d\u044c\u0433\u0438, \u0442\u043e \u043f\u044b\u0442\u0430\u044e\u0441\u044c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0438 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0432\u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u044b. \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043b\u0438? \u041f\u043e\u043a\u0430 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435, \u043d\u043e \u044d\u0442\u043e \u0443\u0436\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0434\u0440\u0443\u0433\u0430\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u044f.\u0410 \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0432\u044b\u0433\u043e\u0440\u0430\u0442\u044c \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u0435, \u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e \u0441\u0435\u0431\u0435 \u0442\u0430\u043a\u0438\u0435 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0435 \u043f\u0435\u0442-\u043f\u0440\u043e\u0435\u043a\u0442\u044b \u2014 UI \u0438\u043b\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0434\u043b\u044f WireMock. \u041e\u043d\u0438 \u043f\u0440\u0438\u043d\u043e\u0441\u044f\u0442 \u0443\u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u0438\u0435, \u0430 \u0437\u0430\u043e\u0434\u043d\u043e \u044d\u043a\u043e\u043d\u043e\u043c\u044f\u0442 \u0432\u0440\u0435\u043c\u044f \u043d\u0430 \u0442\u0435 \u0437\u0430\u0434\u0430\u0447\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043b\u044e\u0431\u043b\u044e.\u041d\u0430 \u0447\u0451\u043c \u044f \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0441\u044f \u0432 \u043f\u0440\u043e\u0448\u043b\u044b\u0439 \u0440\u0430\u0437?\u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 UI \u044f \u043d\u0435 \u0443\u0441\u043f\u0435\u043b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442\u044b.  \u0414\u043b\u044f \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u043e\u0432 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u044b\u0435 \u0441\u0442\u0430\u0431\u044b, \u0430 \u0433\u0438\u0431\u043a\u0438\u0435 \u043c\u043e\u043a\u0438 \u0441 \u043b\u043e\u0433\u0438\u043a\u043e\u0439. WireMock \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u043d\u0430 Java \u0447\u0435\u0440\u0435\u0437 JAR-\u0444\u0430\u0439\u043b\u044b, \u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043a\u0430\u0437\u0430\u043b\u0441\u044f \u043c\u043d\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0433\u0440\u043e\u043c\u043e\u0437\u0434\u043a\u0438\u043c:\u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0438 \u043f\u0438\u0448\u0443\u0442 \u043d\u0430 Python \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u044f\u0437\u044b\u043a\u0430\u0445, \u043d\u0435 \u0444\u0430\u043a\u0442, \u0447\u0442\u043e \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u043a\u043e\u0434\u0438\u0442\u044c \u043d\u0430 Java;\u043b\u044e\u0431\u043e\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0441\u0431\u043e\u0440\u043a\u0438, \u0434\u0435\u043f\u043b\u043e\u044f \u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430 WireMock \u2014 \u044d\u0442\u043e \u043c\u0438\u043d\u0443\u0442\u044b, \u0430 \u043d\u0435 \u0441\u0435\u043a\u0443\u043d\u0434\u044b.\u042f \u043c\u0435\u0447\u0442\u0430\u043b \u043e \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0441\u043a\u0440\u0438\u043f\u0442 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043d\u0430 \u043b\u0435\u0442\u0443 \u0438 \u0441\u0440\u0430\u0437\u0443 \u0432\u0438\u0434\u0435\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u041d\u0443 \u0438 \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0432 \u0442\u0430\u043a\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043d\u0430\u043f\u0438\u0448\u0443\u0442 \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u044b. \u0427\u0442\u043e \u0432 \u0434\u043e\u043b\u0433\u043e\u0441\u0440\u043e\u0447\u043d\u043e\u0439 \u043f\u0435\u0440\u0441\u043f\u0435\u043a\u0442\u0438\u0432\u0435 \u0441\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435.\u042f \u0441\u0442\u0430\u043b \u0438\u0441\u043a\u0430\u0442\u044c \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u0432 wiremock. \u0418 \u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u0445 \u0434\u043b\u044f \u043c\u043e\u043a\u043e\u0432. \u041d\u0430\u0448\u0435\u043b WireMockCoolExtensions. \u041d\u043e \u0442\u0430\u043c \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u043b\u0441\u044f \u0443\u0436\u0435 10 \u043b\u0435\u0442. \u0414\u0430 \u0438 \u043d\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b \u043e\u043d \u043a\u0430\u043a \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0434\u0443\u043a\u0442. \u0421\u0442\u0430\u043b \u0434\u0443\u043c\u0430\u0442\u044c \u043a\u0430\u043a \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c javascript \u0432 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435, \u043d\u043e \u0442\u0443\u0442 \u0432\u0441\u043f\u043b\u044b\u043b\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b:\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c (\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 JS \u0432 JVM \u2014 \u044d\u0442\u043e \u0440\u0438\u0441\u043a),\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u043e\u0442 Nashorn (\u0443\u0441\u0442\u0430\u0440\u0435\u043b) \u0438\u043b\u0438 GraalVM Polyglot (\u0442\u044f\u0436\u0451\u043b\u044b\u0439),WireMock \u0434\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u0441\u0438\u0434\u0438\u0442 \u043d\u0430 Java 11, \u0438 \u043f\u043e\u0434\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438 \u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c.\u042f \u0432\u0437\u0432\u0435\u0441\u0438\u043b \u0432\u0441\u0451 \u0438 \u0440\u0435\u0448\u0438\u043b: \u0432\u0441\u0435\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 JavaScript \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0437\u0430\u0433\u043b\u0443\u0448\u0435\u043a \u043d\u0435 \u043d\u0443\u0436\u043d\u043e. \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0443\u043f\u0440\u043e\u0449\u0451\u043d\u043d\u044b\u0439 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u044b\u0439 \u044f\u0437\u044b\u043a. \u041d\u0430\u0437\u0432\u0430\u043b \u0435\u0433\u043e WiremockJs. \u0414\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u0432\u044b\u0431\u0440\u0430\u043b ANTLR \u2014 \u043c\u043e\u0449\u043d\u044b\u0439 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0435\u043d\u043d\u044b\u0439 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432.\u0418\u0442\u0430\u043a, \u043f\u0435\u0440\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b\u0430 \u0442\u0430\u043a:\u041f\u0435\u0440\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438grammar WiremockJs;script    : statement+ EOF    ;statement    : ifStatement    | returnStatement    ;ifStatement    : IF &#8216;(&#8216; expression &#8216;)&#8217; &#8216;{&#8216; thenStmt+=statement+ &#8216;}&#8217; (ELSE &#8216;{&#8216; elseStmt+=statement+ &#8216;}&#8217;)?    ;returnStatement    : RETURN expression &#8216;;&#8217;    ;expression    : expression op=(&#8216;*&#8217;|&#8217;\/&#8217;|&#8217;%&#8217;) expression        # MulDiv    | expression op=(&#8216;+&#8217;|&#8217;-&#8216;) expression            # AddSub    | expression op=(&#8216;&gt;&#8217;|&#8217;&gt;=&#8217;|'&lt;&#8216;|'&lt;=&#8217;) expression  # Compare    | expression op=(&#8216;==&#8217;|&#8217;!=&#8217;) expression          # Equality    | expression AND expression                     # LogicalAnd    | expression OR expression                      # LogicalOr    | NOT expression                                # LogicalNot    | functionCall                                  # FuncCallExpr    | fieldAccess                                   # FieldAccessExpr    | literal                                       # LiteralExpr    | &#8216;(&#8216; expression &#8216;)&#8217;                            # ParenExpr    ;functionCall    : IDENTIFIER &#8216;(&#8216; argumentList? &#8216;)&#8217;    ;argumentList    : expression (&#8216;,&#8217; expression)*    ;fieldAccess    : IDENTIFIER (&#8216;.&#8217; IDENTIFIER)*    ;literal    : STRING    | NUMBER    | BOOLEAN    | jsonObject    ;jsonObject    : &#8216;{&#8216; (jsonPair (&#8216;,&#8217; jsonPair)*)? &#8216;}&#8217;    ;jsonPair    : STRING &#8216;:&#8217; expression    ;IF: &#8216;if&#8217;;ELSE: &#8216;else&#8217;;RETURN: &#8216;return&#8217;;AND: &#8216;&amp;&amp;&#8217;;OR: &#8216;||&#8217;;NOT: &#8216;!&#8217;;BOOLEAN: &#8216;true&#8217; | &#8216;false&#8217;;NUMBER: &#8216;-&#8216;? [0-9]+ (&#8216;.&#8217; [0-9]+)?;STRING: &#8216;&#187;&#8216; (~[&#171;\\\\] | &#8216;\\\\&#8217; .)* &#8216;&#187;&#8216;;IDENTIFIER: [a-zA-Z_][a-zA-Z0-9_]*;WS: [ \\t\\r\\n]+ -&gt; skip;COMMENT: &#8216;\/\/&#8217; ~[\\r\\n]* -&gt; skip; \u041a\u0430\u043a \u0432\u0438\u0434\u0438\u0442\u0435 \u043f\u0440\u0430\u0432\u0438\u043b \u043d\u0435 \u0442\u0430\u043a \u043c\u043d\u043e\u0433\u043e. \u041d\u0435\u0442 \u0446\u0438\u043a\u043b\u043e\u0432, \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0438 \u043c\u043d\u043e\u0433\u043e \u0447\u0435\u0433\u043e. \u041d\u0430 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043c\u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0438 \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0443 \u0434\u043b\u044f \u044f\u0437\u044b\u043a\u0430. \u041f\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c javascript. \u0418 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442 \u0438 \u043b\u0435\u0433\u043a\u043e \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u0442\u044c \u043a \u0441\u0442\u0430\u0431\u0443. \u0418 \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043b\u043e\u0441\u044c.  \u0423 wiremock \u0435\u0441\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d \u0438\u043b\u0438 \u043f\u0440\u0438\u043c\u0435\u0440 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435: wiremock-extension-template\u0427\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0443 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043d\u0443\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438.\u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u0432 gradle    antlr &#8216;org.antlr:antlr4:4.13.2&#8217;    implementation &#8216;org.antlr:antlr4-runtime:4.13.2&#8217;antlr &#8216;org.antlr:antlr4:4.13.2&#8217;: \u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430. \u041f\u043b\u0430\u0433\u0438\u043d antlr \u0432 Gradle \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u044d\u0442\u0443 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c ANTLR Tool \u0438 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c Java-\u043a\u043b\u0430\u0441\u0441\u044b \u0438\u0437 .g4 \u0444\u0430\u0439\u043b\u043e\u0432 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u042d\u0442\u0438 \u043a\u043b\u0430\u0441\u0441\u044b \u043f\u043e\u044f\u0432\u044f\u0442\u0441\u044f \u0432 \u043f\u0430\u043f\u043a\u0435 build\/generated-src\/&#8230; \u0438 \u0431\u0443\u0434\u0443\u0442 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c.implementation &#8216;org.antlr:antlr4-runtime:4.13.2&#8217;: \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f.  \u0427\u0442\u043e\u0431\u044b \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u043c\u043e\u0433\u043b\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435 (\u043a\u043e\u0433\u0434\u0430 WireMock \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441): \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0442\u043e\u043a\u0435\u043d\u044b, \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0434\u0435\u0440\u0435\u0432\u044c\u044f \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u0438 \u043e\u0431\u0445\u043e\u0434\u0438\u0442\u044c \u0438\u0445B \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043d\u0443\u0436\u043d\u043e \u0435\u0449\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0430\u043f\u043a\u0443 src\/main\/antlr (\u0435\u0451 \u043d\u0435\u0442 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e) \u0438 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435 \u0442\u0443\u0434\u0430 \u043d\u0430\u0448 WiremockJs.g4\u0414\u0430\u043b\u044c\u0448\u0435 \u0432 \u0445\u043e\u0434\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0430 \u044f\u0437\u044b\u043a\u0430 \u043f\u0440\u0435\u0442\u0435\u0440\u043f\u0435\u043b\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0438 \u0441\u0442\u0430\u043b\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:\u041f\u043e\u043b\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438grammar WiremockJs;script    : statement+ EOF    ;statement    : ifStatement    | returnStatement    | varDeclaration    | forEachStatement    ;forEachStatement    : FOR &#8216;(&#8216; VAR IDENTIFIER OF expression &#8216;)&#8217; &#8216;{&#8216; statement* &#8216;}&#8217;    ;varDeclaration    : VAR IDENTIFIER &#8216;=&#8217; expression &#8216;;&#8217;    ;ifStatement    : IF &#8216;(&#8216; expression &#8216;)&#8217; &#8216;{&#8216; thenStmt+=statement+ &#8216;}&#8217; (ELSE &#8216;{&#8216; elseStmt+=statement+ &#8216;}&#8217;)?    ;returnStatement    : RETURN expression &#8216;;&#8217;    ;expression    : expression op=(&#8216;*&#8217;|&#8217;\/&#8217;|&#8217;%&#8217;) expression        # MulDiv    | expression op=(&#8216;+&#8217;|&#8217;-&#8216;) expression            # AddSub    | expression op=(&#8216;&gt;&#8217;|&#8217;&gt;=&#8217;|'&lt;&#8216;|'&lt;=&#8217;) expression  # Compare    | expression op=(&#8216;==&#8217;|&#8217;!=&#8217;) expression          # Equality    | expression AND expression                     # LogicalAnd    | expression OR expression                      # LogicalOr    | NOT expression                                # LogicalNot    | functionCall                                  # FuncCallExpr    | fieldAccess                                   # FieldAccessExpr    | IDENTIFIER                                     # VarRefExpr    | literal                                       # LiteralExpr    | &#8216;(&#8216; expression &#8216;)&#8217;                            # ParenExpr    ;functionCall    : IDENTIFIER &#8216;(&#8216; argumentList? &#8216;)&#8217;    ;argumentList    : expression (&#8216;,&#8217;&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-489628","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/489628","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=489628"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/489628\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=489628"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=489628"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=489628"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}