Best JavaScript code snippet using ts-auto-mock
angular-generator.test.ts
Source:angular-generator.test.ts
...37 mocha.it("Empty JsxOpeningElement", function () {38 assert.strictEqual(39 generator40 .createJsxOpeningElement(41 generator.createIdentifier("div"),42 undefined,43 undefined44 )45 .toString(),46 "<div >"47 );48 });49 mocha.it(50 "Empty JsxSelfClosingElement should have opening and closing tags",51 function () {52 assert.strictEqual(53 generator54 .createJsxSelfClosingElement(55 generator.createIdentifier("div"),56 undefined,57 undefined58 )59 .toString(),60 "<div ></div>"61 );62 }63 );64 mocha.it("Void elements should be self-closing", function () {65 assert.strictEqual(66 generator67 .createJsxSelfClosingElement(68 generator.createIdentifier("img"),69 undefined,70 undefined71 )72 .toString(),73 "<img />"74 );75 });76 mocha.it(`JsxAttribute with expression - [attr]="value"`, function () {77 const expression = generator.createJsxAttribute(78 generator.createIdentifier("attr"),79 generator.createJsxExpression(80 undefined,81 generator.createIdentifier("value")82 )83 );84 assert.strictEqual(expression.toString(), `[attr]="value"`);85 });86 mocha.it(87 `process title attribute - use empty string if value is undefined"`,88 function () {89 const expression = generator.createJsxAttribute(90 generator.createIdentifier("title"),91 generator.createJsxExpression(92 undefined,93 generator.createIdentifier("value")94 )95 );96 assert.strictEqual(97 expression.toString(),98 `[title]="value!==undefined?value:''"`99 );100 }101 );102 mocha.it(103 `do not process title attribute if it stringLiteral value"`,104 function () {105 const expression = generator.createJsxAttribute(106 generator.createIdentifier("title"),107 generator.createStringLiteral("value")108 );109 assert.strictEqual(expression.toString(), `title="value"`);110 }111 );112 mocha.it(113 `JsxAttribute with template expression - [attr]="string concatenation"`,114 function () {115 const templateExpression = generator.createTemplateExpression(116 generator.createTemplateHead("a"),117 [118 generator.createTemplateSpan(119 generator.createNumericLiteral("1"),120 generator.createTemplateMiddle("b")121 ),122 generator.createTemplateSpan(123 generator.createNumericLiteral("2"),124 generator.createTemplateTail("c")125 ),126 ]127 );128 const expression = generator.createJsxAttribute(129 generator.createIdentifier("attr"),130 generator.createJsxExpression(undefined, templateExpression)131 );132 assert.strictEqual(expression.toString(), `[attr]="'a'+1+'b'+2+'c'"`);133 }134 );135 mocha.it("JsxAttribute without initializer", function () {136 const expression = generator.createJsxAttribute(137 generator.createIdentifier("a"),138 undefined139 );140 assert.strictEqual(141 removeSpaces(expression.toString()),142 removeSpaces(`[a]="true"`)143 );144 });145 mocha.it(146 `JsxAttribute with string literal expression - attr="value"`,147 function () {148 const expression = generator.createJsxAttribute(149 generator.createIdentifier("attr"),150 generator.createStringLiteral("value")151 );152 assert.strictEqual(expression.toString(), `attr="value"`);153 }154 );155 mocha.it(156 `JsxAttribute is JsxExpression with stringLiteral - attr="value"`,157 function () {158 const expression = generator.createJsxAttribute(159 generator.createIdentifier("attr"),160 generator.createJsxExpression(161 undefined,162 generator.createStringLiteral("value")163 )164 );165 assert.strictEqual(expression.toString(), `attr="value"`);166 }167 );168 mocha.it(`aria-label attribute binding - [attr.aria-label]"`, function () {169 const expression = generator.createJsxAttribute(170 generator.createIdentifier("aria-label"),171 generator.createJsxExpression(172 undefined,173 generator.createIdentifier("value")174 )175 );176 assert.strictEqual(expression.toString(), `[attr.aria-label]="value"`);177 });178 mocha.it(`aria-label attribute - aria-label"`, function () {179 const expression = generator.createJsxAttribute(180 generator.createIdentifier("aria-label"),181 generator.createJsxExpression(182 undefined,183 generator.createStringLiteral("value")184 )185 );186 assert.strictEqual(expression.toString(), `aria-label="value"`);187 });188 mocha.it("JsxSelfClosingElement with attributes", function () {189 const expression = generator.createJsxSelfClosingElement(190 generator.createIdentifier("div"),191 [],192 generator.createJsxAttributes([193 generator.createJsxAttribute(194 generator.createIdentifier("a1"),195 generator.createNumericLiteral("10")196 ),197 generator.createJsxAttribute(198 generator.createIdentifier("a2"),199 generator.createNumericLiteral("15")200 ),201 ])202 );203 assert.strictEqual(204 expression.toString(),205 `<div [a1]="10"\n[a2]="15"></div>`206 );207 });208 mocha.describe("JsxAttribute SVG with svg", function () {209 mocha.it("name -> [attr.name]", function () {210 const attrName = "height";211 const attribute = generator.createJsxAttribute(212 generator.createIdentifier(attrName),213 generator.createJsxExpression(214 undefined,215 generator.createNumericLiteral("10")216 )217 );218 assert.strictEqual(219 attribute.toString({220 members: [],221 isSVG: true,222 }),223 `[attr.${attrName}]="10"`,224 attrName225 );226 });227 mocha.it("className->attr.class", function () {228 const attrName = "class";229 const attribute = generator.createJsxAttribute(230 generator.createIdentifier(attrName),231 generator.createJsxExpression(232 undefined,233 generator.createNumericLiteral("10")234 )235 );236 assert.strictEqual(237 attribute.toString({238 members: [],239 isSVG: true,240 }),241 `[attr.${attrName}]="10"`,242 attrName243 );244 });245 mocha.it("camelCase -> camel-case", function () {246 const attribute = generator.createJsxAttribute(247 generator.createIdentifier("strokeWidth"),248 generator.createJsxExpression(249 undefined,250 generator.createNumericLiteral("10")251 )252 );253 assert.strictEqual(254 attribute.toString({255 members: [],256 isSVG: true,257 }),258 `[attr.stroke-width]="10"`259 );260 });261 mocha.it("Do not use attr.binding for string literal value", function () {262 const attribute = generator.createJsxAttribute(263 generator.createIdentifier("width"),264 generator.createJsxExpression(265 undefined,266 generator.createStringLiteral("10px")267 )268 );269 assert.strictEqual(270 attribute.toString({271 members: [],272 isSVG: true,273 }),274 'width="10px"'275 );276 });277 mocha.it("do not dasherize not-kebab-case attribute", function () {278 const expression = generator.createJsxAttribute(279 generator.createIdentifier("viewBox"),280 generator.createJsxExpression(281 undefined,282 generator.createIdentifier("value")283 )284 );285 assert.strictEqual(286 expression.toString({287 members: [],288 isSVG: true,289 }),290 `[attr.viewBox]="value"`291 );292 });293 });294 mocha.it("JSX element with Opening and Close Elements", function () {295 const expression = generator.createJsxElement(296 generator.createJsxOpeningElement(297 generator.createIdentifier("div"),298 undefined,299 generator.createJsxAttributes([300 generator.createJsxAttribute(301 generator.createIdentifier("a"),302 generator.createIdentifier("value")303 ),304 ])305 ),306 [],307 generator.createJsxClosingElement(generator.createIdentifier("div"))308 );309 assert.strictEqual(expression.toString(), '<div [a]="value"></div>');310 });311 mocha.it("JsxElement: trim spaces in string children", function () {312 const expression = generator.createJsxElement(313 generator.createJsxOpeningElement(314 generator.createIdentifier("div"),315 undefined,316 []317 ),318 [" a "],319 generator.createJsxClosingElement(generator.createIdentifier("div"))320 );321 assert.strictEqual(expression.toString(), "<div >a</div>");322 });323 mocha.it("Fragment should be ignored", function () {324 const expression = generator.createJsxElement(325 generator.createJsxOpeningElement(326 generator.createIdentifier("Fragment"),327 undefined,328 undefined329 ),330 [331 generator.createJsxSelfClosingElement(332 generator.createIdentifier("div")333 ),334 ],335 generator.createJsxClosingElement(336 generator.createIdentifier("Fragment")337 )338 );339 assert.strictEqual(expression.toString(), "<div ></div>");340 });341 mocha.it("JSX element with with child element", function () {342 const expression = generator.createJsxElement(343 generator.createJsxOpeningElement(344 generator.createIdentifier("parent"),345 undefined,346 []347 ),348 [349 generator.createJsxSelfClosingElement(350 generator.createIdentifier("child")351 ),352 ],353 generator.createJsxClosingElement(generator.createIdentifier("parent"))354 );355 assert.strictEqual(356 expression.toString(),357 "<parent ><child ></child></parent>"358 );359 });360 mocha.it("Pass svg children into component", function () {361 const component = createComponent([362 generator.createProperty(363 [364 createDecorator(Decorators.Slot, {365 isSVG: generator.createTrue(),366 }),367 ],368 [],369 generator.createIdentifier("children")370 ),371 ]);372 const expression = generator.createJsxElement(373 generator.createJsxOpeningElement(component._name),374 [375 generator.createJsxSelfClosingElement(376 generator.createIdentifier("text")377 ),378 ],379 generator.createJsxClosingElement(component._name)380 );381 assert.strictEqual(382 expression.toString(),383 "<dx-base-widget ><svg:text ></text></dx-base-widget>"384 );385 });386 mocha.it(387 "Pass not svg children into svg widget - throw exception",388 function () {389 const component = createComponent(390 [391 generator.createProperty(392 [createDecorator(Decorators.Slot)],393 [],394 generator.createIdentifier("children")395 ),396 ],397 {398 isSVG: generator.createTrue(),399 }400 );401 const expression = generator.createJsxElement(402 generator.createJsxOpeningElement(component._name),403 [404 generator.createJsxExpression(405 undefined,406 generator.createPropertyAccess(407 generator.createIdentifier("viewModel"),408 generator.createIdentifier("children")409 )410 ),411 ],412 generator.createJsxClosingElement(component._name)413 );414 let error: string | null = null;415 try {416 expression.toString({417 members: [418 generator.createProperty(419 [createDecorator(Decorators.Slot)],420 [],421 generator.createIdentifier("children")422 ),423 ],424 componentContext: "viewModel",425 newComponentContext: "",426 });427 } catch (e) {428 error = e;429 }430 assert.strictEqual(431 error,432 "Can't pass children slot into BaseWidget: Use @Slot({isSVG: true})"433 );434 }435 );436 mocha.it(437 "JSX element with with child element that transformed from expression - no wrap it {{}}",438 function () {439 const expression = generator.createJsxElement(440 generator.createJsxOpeningElement(441 generator.createIdentifier("parent"),442 undefined,443 []444 ),445 [446 generator.createJsxExpression(447 undefined,448 generator.createBinary(449 generator.createTrue(),450 generator.createToken(451 generator.SyntaxKind.AmpersandAmpersandToken452 ),453 generator.createJsxElement(454 generator.createJsxOpeningElement(455 generator.createIdentifier("child"),456 undefined,457 []458 ),459 [],460 generator.createJsxClosingElement(461 generator.createIdentifier("child")462 )463 )464 )465 ),466 ],467 generator.createJsxClosingElement(468 generator.createIdentifier("parent")469 )470 );471 assert.strictEqual(472 expression.toString(),473 `<parent ><child *ngIf="true"></child></parent>`474 );475 }476 );477 mocha.it(478 `<element>{"text"}</element> -> <element>text</element>`,479 function () {480 const expression = generator.createJsxElement(481 generator.createJsxOpeningElement(482 generator.createIdentifier("element"),483 undefined,484 []485 ),486 [487 generator.createJsxExpression(488 undefined,489 generator.createStringLiteral("text")490 ),491 ],492 generator.createJsxClosingElement(493 generator.createIdentifier("element")494 )495 );496 assert.strictEqual(expression.toString(), `<element >text</element>`);497 }498 );499 mocha.it("Rename className attribute to class", function () {500 const expression = generator.createJsxAttribute(501 generator.createIdentifier("className"),502 generator.createJsxExpression(503 undefined,504 generator.createIdentifier("value")505 )506 );507 assert.strictEqual(expression.toString(), `[class]="value"`);508 });509 mocha.it("Rename style attribute to ngStyle", function () {510 const expression = generator.createJsxAttribute(511 generator.createIdentifier("style"),512 generator.createJsxExpression(513 undefined,514 generator.createIdentifier("value")515 )516 );517 assert.strictEqual(518 expression.toString(),519 `[ngStyle]="__processNgStyle(value)"`520 );521 });522 mocha.it(523 "notJsxExpr && <element></element> -> <element *ngIf='notJsxExpr'></element>",524 function () {525 const expression = generator.createJsxElement(526 generator.createJsxOpeningElement(527 generator.createIdentifier("div"),528 undefined,529 []530 ),531 [532 generator.createJsxExpression(533 undefined,534 generator.createBinary(535 generator.createPropertyAccess(536 generator.createIdentifier("viewModel"),537 generator.createIdentifier("input")538 ),539 generator.createToken(540 generator.SyntaxKind.AmpersandAmpersandToken541 ),542 generator.createJsxElement(543 generator.createJsxOpeningElement(544 generator.createIdentifier("input"),545 undefined,546 generator.createJsxAttributes([])547 ),548 [],549 generator.createJsxClosingElement(550 generator.createIdentifier("input")551 )552 )553 )554 ),555 ],556 generator.createJsxClosingElement(generator.createIdentifier("div"))557 );558 assert.strictEqual(559 expression.children[0].toString(),560 `<input *ngIf="viewModel.input"></input>`561 );562 }563 );564 mocha.it("Binary operator in attribute", function () {565 const expression = generator.createJsxSelfClosingElement(566 generator.createIdentifier("input"),567 undefined,568 [569 generator.createJsxAttribute(570 generator.createIdentifier("a"),571 generator.createJsxExpression(572 undefined,573 generator.createBinary(574 generator.createIdentifier("s1"),575 generator.SyntaxKind.PlusToken,576 generator.createIdentifier("s2")577 )578 )579 ),580 ]581 );582 assert.strictEqual(expression.toString(), `<input [a]="s1 + s2"/>`);583 });584 mocha.it(585 "not supported binary expression in JsxExpression - throw exception",586 function () {587 const expression = generator.createJsxElement(588 generator.createJsxOpeningElement(589 generator.createIdentifier("div"),590 undefined,591 []592 ),593 [594 generator.createJsxExpression(595 undefined,596 generator.createBinary(597 generator.createPropertyAccess(598 generator.createIdentifier("viewModel"),599 generator.createIdentifier("input")600 ),601 generator.createToken(generator.SyntaxKind.PlusToken),602 generator.createJsxElement(603 generator.createJsxOpeningElement(604 generator.createIdentifier("input"),605 undefined,606 generator.createJsxAttributes([])607 ),608 [],609 generator.createJsxClosingElement(610 generator.createIdentifier("input")611 )612 )613 )614 ),615 ],616 generator.createJsxClosingElement(generator.createIdentifier("div"))617 );618 let error;619 try {620 expression.toString();621 } catch (e) {622 error = e;623 }624 assert.strictEqual(625 error,626 "Operator + is not supported: viewModel.input + <input ></input>"627 );628 }629 );630 mocha.it("non jsx binary in element", function () {631 const expression = generator.createJsxElement(632 generator.createJsxOpeningElement(633 generator.createIdentifier("div"),634 undefined,635 []636 ),637 [638 generator.createJsxExpression(639 undefined,640 generator.createBinary(641 generator.createIdentifier("s1"),642 generator.SyntaxKind.PlusToken,643 generator.createIdentifier("s2")644 )645 ),646 ],647 generator.createJsxClosingElement(generator.createIdentifier("div"))648 );649 assert.strictEqual(expression.toString(), "<div >{{s1 + s2}}</div>");650 });651 mocha.it(652 "notJsxExpr && <element/> -> <element *ngIf='notJsxExpr' />",653 function () {654 const expression = generator.createJsxElement(655 generator.createJsxOpeningElement(656 generator.createIdentifier("div"),657 undefined,658 []659 ),660 [661 generator.createJsxExpression(662 undefined,663 generator.createBinary(664 generator.createPropertyAccess(665 generator.createIdentifier("viewModel"),666 generator.createIdentifier("input")667 ),668 generator.createToken(669 generator.SyntaxKind.AmpersandAmpersandToken670 ),671 generator.createJsxSelfClosingElement(672 generator.createIdentifier("input"),673 undefined,674 generator.createJsxAttributes([])675 )676 )677 ),678 ],679 generator.createJsxClosingElement(generator.createIdentifier("div"))680 );681 assert.strictEqual(682 expression.children[0].toString(),683 `<input *ngIf="viewModel.input"/>`684 );685 }686 );687 mocha.it(688 "ngIf directive with string - replace quotes with backslash quotes",689 function () {690 const expression = generator.createJsxElement(691 generator.createJsxOpeningElement(692 generator.createIdentifier("div"),693 undefined,694 []695 ),696 [697 generator.createJsxExpression(698 undefined,699 generator.createBinary(700 generator.createBinary(701 generator.createIdentifier("viewModel"),702 generator.SyntaxKind.EqualsEqualsEqualsToken,703 generator.createStringLiteral("input")704 ),705 generator.createToken(706 generator.SyntaxKind.AmpersandAmpersandToken707 ),708 generator.createJsxSelfClosingElement(709 generator.createIdentifier("input"),710 undefined,711 generator.createJsxAttributes([])712 )713 )714 ),715 ],716 generator.createJsxClosingElement(generator.createIdentifier("div"))717 );718 assert.strictEqual(719 expression.children[0].toString(),720 `<input *ngIf="viewModel === 'input'"/>`721 );722 }723 );724 mocha.it(725 "condition?then:else - <div ngIf='condition'> <div ngIf='!(condition)'",726 function () {727 const attribute = generator.createJsxAttribute(728 generator.createIdentifier("a"),729 generator.createPropertyAccess(730 generator.createIdentifier("viewModel"),731 generator.createIdentifier("value")732 )733 );734 const property = generator.createGetAccessor(735 [],736 [],737 generator.createIdentifier("value"),738 [],739 undefined,740 undefined741 );742 property.prefix = "_";743 const expression = generator.createJsxElement(744 generator.createJsxOpeningElement(745 generator.createIdentifier("div"),746 undefined,747 []748 ),749 [750 generator.createJsxExpression(751 undefined,752 generator.createConditional(753 generator.createIdentifier("condition"),754 generator.createJsxSelfClosingElement(755 generator.createIdentifier("div"),756 [],757 [attribute]758 ),759 generator.createJsxSelfClosingElement(760 generator.createIdentifier("input"),761 [],762 [attribute]763 )764 )765 ),766 ],767 generator.createJsxClosingElement(generator.createIdentifier("div"))768 );769 assert.strictEqual(770 removeSpaces(771 expression.children[0].toString({772 componentContext: "viewModel",773 newComponentContext: "",774 members: [property],775 })776 ),777 removeSpaces(778 `<div [a]="_value" *ngIf="condition"></div>\n<input [a]="_value" *ngIf="!(condition)"/>`779 )780 );781 }782 );783 mocha.it(784 "non jsx conditional - condition?then:else - {{then}} {{else}}'",785 function () {786 const thenStatement = generator.createPropertyAccess(787 generator.createIdentifier("viewModel"),788 generator.createIdentifier("value")789 );790 const elseStatement = generator.createPrefix(791 generator.SyntaxKind.ExclamationToken,792 generator.createPropertyAccess(793 generator.createIdentifier("viewModel"),794 generator.createIdentifier("value")795 )796 );797 const property = generator.createGetAccessor(798 [],799 [],800 generator.createIdentifier("value"),801 [],802 undefined,803 undefined804 );805 property.prefix = "_";806 const expression = generator.createJsxElement(807 generator.createJsxOpeningElement(808 generator.createIdentifier("div"),809 undefined,810 []811 ),812 [813 generator.createJsxExpression(814 undefined,815 generator.createConditional(816 generator.createIdentifier("condition"),817 thenStatement,818 elseStatement819 )820 ),821 ],822 generator.createJsxClosingElement(generator.createIdentifier("div"))823 );824 assert.strictEqual(825 removeSpaces(826 expression.children[0].toString({827 componentContext: "viewModel",828 newComponentContext: "",829 members: [property],830 })831 ),832 removeSpaces(833 `<ng-container *ngIf="condition">834 {{_value}}835 </ng-container>836 <ng-container *ngIf="!(condition)">837 {{!_value}}838 </ng-container>`839 )840 );841 }842 );843 mocha.it("conditional expression with paren", function () {844 const expression = generator.createJsxElement(845 generator.createJsxOpeningElement(846 generator.createIdentifier("div"),847 undefined,848 []849 ),850 [851 generator.createJsxExpression(852 undefined,853 generator.createConditional(854 generator.createIdentifier("condition"),855 generator.createParen(856 generator.createJsxSelfClosingElement(857 generator.createIdentifier("div"),858 [],859 []860 )861 ),862 generator.createParen(863 generator.createJsxSelfClosingElement(864 generator.createIdentifier("input"),865 [],866 []867 )868 )869 )870 ),871 ],872 generator.createJsxClosingElement(generator.createIdentifier("div"))873 );874 assert.strictEqual(875 removeSpaces(expression.children[0].toString()),876 removeSpaces(877 `<div *ngIf="condition"></div>\n<input *ngIf="!(condition)"/>`878 )879 );880 });881 mocha.it(882 "<element>nonJsxExpr</element> -> <element>{{nonJsxExpr}}</element>",883 function () {884 const expression = generator.createJsxElement(885 generator.createJsxOpeningElement(886 generator.createIdentifier("span"),887 undefined,888 []889 ),890 [891 generator.createJsxExpression(892 undefined,893 generator.createPropertyAccess(894 generator.createIdentifier("viewModel"),895 generator.createIdentifier("text")896 )897 ),898 ],899 generator.createJsxClosingElement(generator.createIdentifier("span"))900 );901 assert.strictEqual(902 expression.toString(),903 "<span >{{viewModel.text}}</span>"904 );905 }906 );907 mocha.it("render element from variable", function () {908 const variable = generator.createJsxElement(909 generator.createJsxOpeningElement(910 generator.createIdentifier("span"),911 undefined,912 []913 ),914 [],915 generator.createJsxClosingElement(generator.createIdentifier("span"))916 );917 const expression = generator.createJsxElement(918 generator.createJsxOpeningElement(919 generator.createIdentifier("div"),920 undefined,921 []922 ),923 [924 generator.createJsxExpression(925 undefined,926 generator.createIdentifier("var")927 ),928 ],929 generator.createJsxClosingElement(generator.createIdentifier("div"))930 );931 assert.strictEqual(932 expression.toString({933 members: [],934 variables: {935 var: variable,936 },937 }),938 `<div ><ng-container *ngTemplateOutlet="var"></ng-container></div>`939 );940 });941 mocha.it(942 "render element from variable in condition expression in parens",943 function () {944 const variable = generator.createParen(945 generator.createJsxElement(946 generator.createJsxOpeningElement(947 generator.createIdentifier("span"),948 undefined,949 []950 ),951 [],952 generator.createJsxClosingElement(953 generator.createIdentifier("span")954 )955 )956 );957 const expression = generator.createJsxElement(958 generator.createJsxOpeningElement(959 generator.createIdentifier("div"),960 undefined,961 []962 ),963 [964 generator.createJsxExpression(965 undefined,966 generator.createConditional(967 generator.createIdentifier("condition"),968 generator.createParen(generator.createIdentifier("var")),969 generator.createParen(generator.createIdentifier("var"))970 )971 ),972 ],973 generator.createJsxClosingElement(generator.createIdentifier("div"))974 );975 assert.strictEqual(976 removeSpaces(977 expression.toString({978 members: [],979 variables: {980 var: variable,981 },982 })983 ),984 removeSpaces(`985 <div >986 <ng-container *ngIf="condition"> 987 <ng-container *ngTemplateOutlet="var"></ng-container>988 </ng-container>989 <ng-container *ngIf="!(condition)">990 <ng-container *ngTemplateOutlet="var"></ng-container>991 </ng-container>992 </div>`)993 );994 }995 );996 mocha.it("render element from variable in condition", function () {997 const variable = generator.createJsxElement(998 generator.createJsxOpeningElement(999 generator.createIdentifier("span"),1000 undefined,1001 []1002 ),1003 [],1004 generator.createJsxClosingElement(generator.createIdentifier("span"))1005 );1006 const expression = generator.createJsxElement(1007 generator.createJsxOpeningElement(1008 generator.createIdentifier("div"),1009 undefined,1010 []1011 ),1012 [1013 generator.createJsxExpression(1014 undefined,1015 generator.createConditional(1016 generator.createIdentifier("condition"),1017 generator.createIdentifier("var"),1018 generator.createIdentifier("var")1019 )1020 ),1021 ],1022 generator.createJsxClosingElement(generator.createIdentifier("div"))1023 );1024 assert.strictEqual(1025 removeSpaces(1026 expression.toString({1027 members: [],1028 variables: {1029 var: variable,1030 },1031 })1032 ),1033 removeSpaces(`1034 <div >1035 <ng-container *ngIf="condition"> 1036 <ng-container *ngTemplateOutlet="var"></ng-container>1037 </ng-container>1038 <ng-container *ngIf="!(condition)">1039 <ng-container *ngTemplateOutlet="var"></ng-container>1040 </ng-container>1041 </div>`)1042 );1043 });1044 mocha.describe("Dynamic components", function () {1045 mocha.it(1046 "<DynamicComponent /> -> <ng-template dynamicComponent>",1047 function () {1048 const getterName = "DynamicComponent";1049 const getter = generator.createGetAccessor(1050 [],1051 undefined,1052 generator.createIdentifier(getterName),1053 [],1054 undefined,1055 generator.createBlock([], false)1056 );1057 const element = generator.createJsxSelfClosingElement(1058 generator.createPropertyAccess(1059 generator.createIdentifier("viewModel"),1060 generator.createIdentifier(getterName)1061 )1062 );1063 const options: toStringOptions = {1064 members: [getter],1065 componentContext: "viewModel",1066 newComponentContext: "",1067 };1068 assert.strictEqual(1069 removeSpaces(element.toString(options)),1070 removeSpaces(`1071 <ng-template dynamicComponent1072 [props]="{}"1073 [componentConstructor]="DynamicComponent"1074 let-DynamicComponent="DynamicComponent"1075 >1076 </ng-template>`)1077 );1078 assert.strictEqual(options.hasDynamicComponents, true);1079 }1080 );1081 mocha.it("<DynamicComponent [props]='value'/>", function () {1082 const getterName = "DynamicComponent";1083 const getter = generator.createGetAccessor(1084 [],1085 undefined,1086 generator.createIdentifier(getterName),1087 [],1088 undefined,1089 generator.createBlock([], false)1090 );1091 const element = generator.createJsxSelfClosingElement(1092 generator.createPropertyAccess(1093 generator.createIdentifier("viewModel"),1094 generator.createIdentifier(getterName)1095 ),1096 undefined,1097 [1098 generator.createJsxAttribute(1099 generator.createIdentifier("prop1"),1100 generator.createStringLiteral("value1")1101 ),1102 generator.createJsxAttribute(1103 generator.createIdentifier("prop2"),1104 generator.createStringLiteral("value2")1105 ),1106 ]1107 );1108 const options: toStringOptions = {1109 members: [getter],1110 componentContext: "viewModel",1111 newComponentContext: "",1112 };1113 assert.strictEqual(1114 removeSpaces(element.toString(options)),1115 removeSpaces(`1116 <ng-template dynamicComponent1117 [props]="{prop1:'value1',prop2:'value2'}"1118 [componentConstructor]="DynamicComponent"1119 let-DynamicComponent="DynamicComponent">1120 </ng-template>`)1121 );1122 });1123 mocha.it("<DynamicComponent with spreadProps/>", function () {1124 const getterName = "DynamicComponent";1125 const getter = generator.createGetAccessor(1126 [],1127 undefined,1128 generator.createIdentifier(getterName),1129 [],1130 undefined,1131 generator.createBlock([], false)1132 );1133 const element = generator.createJsxSelfClosingElement(1134 generator.createPropertyAccess(1135 generator.createIdentifier("viewModel"),1136 generator.createIdentifier(getterName)1137 ),1138 undefined,1139 [1140 generator.createJsxAttribute(1141 generator.createIdentifier("prop1"),1142 generator.createIdentifier("value1")1143 ),1144 generator.createJsxSpreadAttribute(1145 generator.createIdentifier("spreadValue")1146 ),1147 generator.createJsxAttribute(1148 generator.createIdentifier("prop2"),1149 generator.createStringLiteral("value2")1150 ),1151 generator.createJsxSpreadAttribute(1152 generator.createIdentifier("oneMoreSpread")1153 ),1154 ]1155 );1156 const options: toStringOptions = {1157 members: [getter],1158 componentContext: "viewModel",1159 newComponentContext: "",1160 };1161 assert.strictEqual(1162 removeSpaces(element.toString(options)),1163 removeSpaces(`1164 <ng-template dynamicComponent1165 [props]="{prop1:value1,dxSpreadProp1:spreadValue,prop2:'value2',dxSpreadProp3:oneMoreSpread}"1166 [componentConstructor]="DynamicComponent"1167 let-DynamicComponent="DynamicComponent">1168 </ng-template>`)1169 );1170 });1171 mocha.it(1172 "<DynamicComponent></DynamicComponent> -> <ng-template dynamicComponent>",1173 function () {1174 const getterName = "DynamicComponent";1175 const getter = generator.createGetAccessor(1176 [],1177 undefined,1178 generator.createIdentifier(getterName),1179 [],1180 undefined,1181 generator.createBlock([], false)1182 );1183 const tag = generator.createPropertyAccess(1184 generator.createIdentifier("viewModel"),1185 generator.createIdentifier(getterName)1186 );1187 const element = generator.createJsxElement(1188 generator.createJsxOpeningElement(tag, undefined, []),1189 [],1190 generator.createJsxClosingElement(tag)1191 );1192 assert.strictEqual(1193 removeSpaces(1194 element.toString({1195 members: [getter],1196 componentContext: "viewModel",1197 newComponentContext: "",1198 })1199 ),1200 removeSpaces(`1201 <ng-template dynamicComponent1202 [props]="{}"1203 [componentConstructor]="DynamicComponent"1204 let-DynamicComponent="DynamicComponent">1205 </ng-template>`)1206 );1207 }1208 );1209 mocha.it(1210 "<DynamicComponent template={()=><div/>}/> -> <component><template></component>",1211 function () {1212 const component = createComponent([1213 generator.createProperty(1214 [createDecorator(Decorators.Template)],1215 [],1216 generator.createIdentifier("template")1217 ),1218 ]);1219 const getterName = "DynamicComponent";1220 const getter = generator.createGetAccessor(1221 [],1222 undefined,1223 generator.createIdentifier(getterName),1224 [],1225 generator.createTypeReferenceNode(component._name),1226 generator.createBlock([], false)1227 );1228 const tag = generator.createPropertyAccess(1229 generator.createIdentifier("viewModel"),1230 getter._name1231 );1232 const element = generator.createJsxSelfClosingElement(1233 tag,1234 undefined,1235 [1236 generator.createJsxAttribute(1237 generator.createIdentifier("template"),1238 generator.createJsxExpression(1239 undefined,1240 generator.createArrowFunction(1241 [],1242 undefined,1243 [],1244 undefined,1245 generator.SyntaxKind.EqualsGreaterThanToken,1246 generator.createJsxSelfClosingElement(1247 generator.createIdentifier("div")1248 )1249 )1250 )1251 ),1252 ]1253 );1254 const options: toStringOptions = {1255 members: [getter],1256 componentContext: "viewModel",1257 newComponentContext: "",1258 };1259 assert.strictEqual(1260 removeSpaces(element.toString(options)),1261 removeSpaces(`1262 <ng-template dynamicComponent1263 [props]="{template:__template__generated}"1264 [componentConstructor]="DynamicComponent"1265 let-DynamicComponent="DynamicComponent">1266 </ng-template>1267 <ng-template #__template__generated>1268 <div></div>1269 </ng-template>1270 `)1271 );1272 }1273 );1274 mocha.it("can't parse template", function () {1275 const component = createComponent([1276 generator.createProperty(1277 [createDecorator(Decorators.Template)],1278 [],1279 generator.createIdentifier("template")1280 ),1281 ]);1282 const getterName = "DynamicComponent";1283 const getter = generator.createGetAccessor(1284 [],1285 undefined,1286 generator.createIdentifier(getterName),1287 [],1288 generator.createTypeReferenceNode(component._name),1289 generator.createBlock([], false)1290 );1291 const tag = generator.createPropertyAccess(1292 generator.createIdentifier("viewModel"),1293 getter._name1294 );1295 const element = generator.createJsxSelfClosingElement(tag, undefined, [1296 generator.createJsxAttribute(1297 generator.createIdentifier("template"),1298 generator.createArrowFunction(1299 [],1300 undefined,1301 [],1302 undefined,1303 generator.SyntaxKind.EqualsGreaterThanToken,1304 generator.createJsxSelfClosingElement(1305 generator.createIdentifier("div")1306 )1307 )1308 ),1309 ]);1310 const options: toStringOptions = {1311 members: [getter],1312 componentContext: "viewModel",1313 newComponentContext: "",1314 };1315 assert.strictEqual(1316 removeSpaces(element.toString(options)),1317 removeSpaces(`1318 <ng-template dynamicComponent1319 [props]="{template: null}"1320 [componentConstructor]="DynamicComponent"1321 let-DynamicComponent="DynamicComponent">1322 </ng-template>1323 <ng-template #__template__generated>1324 <div></div>1325 </ng-template>1326 `)1327 );1328 });1329 mocha.it(1330 "<DynamicComponent template={()=><div/>}></DynamicComponent> -> <component><template></component>",1331 function () {1332 const component = createComponent([1333 generator.createProperty(1334 [createDecorator(Decorators.Template)],1335 [],1336 generator.createIdentifier("template")1337 ),1338 ]);1339 const getterName = "DynamicComponent";1340 const getter = generator.createGetAccessor(1341 [],1342 undefined,1343 generator.createIdentifier(getterName),1344 [],1345 generator.createTypeReferenceNode(component._name),1346 generator.createBlock([], false)1347 );1348 const tag = generator.createPropertyAccess(1349 generator.createIdentifier("viewModel"),1350 getter._name1351 );1352 const element = generator.createJsxElement(1353 generator.createJsxOpeningElement(tag, undefined, [1354 generator.createJsxAttribute(1355 generator.createIdentifier("template"),1356 generator.createJsxExpression(1357 undefined,1358 generator.createArrowFunction(1359 [],1360 undefined,1361 [],1362 undefined,1363 generator.SyntaxKind.EqualsGreaterThanToken,1364 generator.createJsxSelfClosingElement(1365 generator.createIdentifier("div")1366 )1367 )1368 )1369 ),1370 ]),1371 [1372 generator.createJsxSelfClosingElement(1373 generator.createIdentifier("div")1374 ),1375 ],1376 generator.createJsxClosingElement(tag)1377 );1378 const options: toStringOptions = {1379 members: [getter],1380 componentContext: "viewModel",1381 newComponentContext: "",1382 };1383 assert.strictEqual(1384 removeSpaces(element.toString(options)),1385 removeSpaces(`1386 <ng-template dynamicComponent1387 [props]="{template:__template__generated}"1388 [componentConstructor]="DynamicComponent"1389 let-DynamicComponent="DynamicComponent">1390 <div></div>1391 </ng-template>1392 <ng-template #__template__generated>1393 <div></div>1394 </ng-template>1395 `)1396 );1397 }1398 );1399 mocha.it(1400 "condition && <DynamicComponent /> -> <ng-template *ngIf dynamicComponent>",1401 function () {1402 const getterName = "DynamicComponent";1403 const getter = generator.createGetAccessor(1404 [],1405 undefined,1406 generator.createIdentifier(getterName),1407 [],1408 undefined,1409 generator.createBlock([], false)1410 );1411 const element = generator.createJsxElement(1412 generator.createJsxOpeningElement(1413 generator.createIdentifier("div")1414 ),1415 [1416 generator.createJsxExpression(1417 undefined,1418 generator.createBinary(1419 generator.createIdentifier("condition"),1420 generator.SyntaxKind.AmpersandAmpersandToken,1421 generator.createJsxSelfClosingElement(1422 generator.createPropertyAccess(1423 generator.createIdentifier("viewModel"),1424 generator.createIdentifier(getterName)1425 )1426 )1427 )1428 ),1429 ],1430 generator.createJsxClosingElement(generator.createIdentifier("div"))1431 );1432 const options: toStringOptions = {1433 members: [getter],1434 componentContext: "viewModel",1435 newComponentContext: "",1436 };1437 assert.strictEqual(1438 removeSpaces(element.toString(options)),1439 removeSpaces(1440 `<div>1441 <ng-template dynamicComponent 1442 *ngIf="condition" 1443 [props]="{}"1444 [componentConstructor]="DynamicComponent"1445 let-DynamicComponent="DynamicComponent">1446 </ng-template>1447 </div>`1448 )1449 );1450 }1451 );1452 mocha.it("map <DynamicComponent />", function () {1453 const getterName = "DynamicComponent";1454 const getter = generator.createGetAccessor(1455 [],1456 undefined,1457 generator.createIdentifier(getterName),1458 [],1459 undefined,1460 generator.createBlock([], false)1461 );1462 const element = generator.createJsxElement(1463 generator.createJsxOpeningElement(generator.createIdentifier("div")),1464 [1465 generator.createJsxExpression(1466 undefined,1467 generator.createCall(1468 generator.createPropertyAccess(1469 generator.createPropertyAccess(1470 generator.createIdentifier("viewModel"),1471 generator.createIdentifier(getterName)1472 ),1473 generator.createIdentifier("map")1474 ),1475 undefined,1476 [1477 generator.createArrowFunction(1478 undefined,1479 undefined,1480 [1481 generator.createParameter(1482 undefined,1483 undefined,1484 undefined,1485 generator.createIdentifier("item"),1486 undefined,1487 undefined,1488 undefined1489 ),1490 generator.createParameter(1491 undefined,1492 undefined,1493 undefined,1494 generator.createIdentifier("index"),1495 undefined,1496 undefined,1497 undefined1498 ),1499 ],1500 undefined,1501 generator.createToken(1502 generator.SyntaxKind.EqualsGreaterThanToken1503 ),1504 generator.createJsxSelfClosingElement(1505 generator.createIdentifier("item"),1506 undefined,1507 [1508 generator.createJsxAttribute(1509 generator.createIdentifier("key"),1510 generator.createIdentifier("index")1511 ),1512 generator.createJsxAttribute(1513 generator.createIdentifier("prop"),1514 generator.createIdentifier("value")1515 ),1516 ]1517 )1518 ),1519 ]1520 )1521 ),1522 ],1523 generator.createJsxClosingElement(generator.createIdentifier("div"))1524 );1525 const options: toStringOptions = {1526 members: [getter],1527 componentContext: "viewModel",1528 newComponentContext: "",1529 };1530 assert.strictEqual(1531 removeSpaces(element.toString(options)),1532 removeSpaces(`<div>1533 <ng-container *ngFor="let item of DynamicComponent; index as index">1534 <ng-template dynamicComponent 1535 [props]="{prop:value}"1536 [componentConstructor]="item"1537 let-DynamicComponent="DynamicComponent"></ng-template>1538 </ng-container>1539 </div>`)1540 );1541 });1542 });1543 mocha.describe("Component", function () {1544 mocha.it("Render himself", function () {1545 const componentName = "BaseWidget";1546 const element = generator.createJsxSelfClosingElement(1547 generator.createIdentifier(componentName)1548 );1549 const component = createComponent([]);1550 assert.strictEqual(component.name, componentName);1551 assert.strictEqual(1552 element.toString({1553 members: [],1554 }),1555 "<dx-base-widget ></dx-base-widget>"1556 );1557 });1558 mocha.it("<SVGComponent/>", function () {1559 const component = createComponent([], {1560 isSVG: generator.createTrue(),1561 });1562 const element = generator.createJsxSelfClosingElement(1563 generator.createIdentifier(component.name)1564 );1565 assert.strictEqual(1566 element.toString({1567 members: [],1568 }),1569 `<g BaseWidget ></g >`1570 );1571 });1572 mocha.it(1573 "render svg component with children inside html component",1574 function () {1575 const component = createComponent([], {1576 isSVG: generator.createTrue(),1577 });1578 const element = generator.createJsxElement(1579 generator.createJsxOpeningElement(1580 generator.createIdentifier("div")1581 ),1582 [1583 generator.createJsxElement(1584 generator.createJsxOpeningElement(component._name),1585 [1586 generator.createJsxSelfClosingElement(1587 generator.createIdentifier("text"),1588 undefined,1589 [1590 generator.createJsxAttribute(1591 generator.createIdentifier("style"),1592 generator.createIdentifier("styleValue")1593 ),1594 ]1595 ),1596 ],1597 generator.createJsxClosingElement(component._name)1598 ),1599 ],1600 generator.createJsxClosingElement(generator.createIdentifier("div"))1601 );1602 const options: toStringOptions = {1603 members: [],1604 isSVG: false,1605 };1606 assert.strictEqual(1607 removeSpaces(element.toString(options)),1608 removeSpaces(`1609 <div>1610 <g BaseWidget >1611 <svg:text [ngStyle]="__processNgStyle(styleValue)"></text>1612 </g >1613 </div>`)1614 );1615 assert.strictEqual(options.isSVG, false);1616 assert.strictEqual(options.hasStyle, true);1617 }1618 );1619 mocha.it("<SVG Component></SVGComponent>", function () {1620 const component = createComponent([], {1621 isSVG: generator.createTrue(),1622 });1623 const element = generator.createJsxElement(1624 generator.createJsxOpeningElement(1625 generator.createIdentifier(component.name)1626 ),1627 [],1628 generator.createJsxClosingElement(1629 generator.createIdentifier(component.name)1630 )1631 );1632 assert.strictEqual(1633 element.toString({1634 members: [],1635 }),1636 `<g BaseWidget ></g >`1637 );1638 });1639 });1640 mocha.describe("Slots with conditional rendering", function () {1641 this.beforeEach(function () {1642 this.slotProperty = generator.createProperty(1643 [createDecorator("Slot")],1644 [],1645 generator.createIdentifier("children"),1646 generator.SyntaxKind.QuestionToken,1647 undefined,1648 undefined1649 );1650 this.slotExpression = generator.createPropertyAccess(1651 generator.createPropertyAccess(1652 generator.createIdentifier("viewModel"),1653 generator.createIdentifier("props")1654 ),1655 generator.createIdentifier("children")1656 );1657 this.toStringOptions = {1658 members: [this.slotProperty],1659 componentContext: "viewModel",1660 newComponentContext: "",1661 } as toStringOptions;1662 });1663 function createElement(children: JsxExpression[]) {1664 return generator.createJsxElement(1665 generator.createJsxOpeningElement(1666 generator.createIdentifier("div"),1667 undefined,1668 []1669 ),1670 children,1671 generator.createJsxClosingElement(generator.createIdentifier("div"))1672 );1673 }1674 mocha.it("slot? slot: alternative content", function () {1675 const element = createElement([1676 generator.createJsxExpression(1677 undefined,1678 generator.createConditional(1679 this.slotExpression,1680 this.slotExpression,1681 generator.createIdentifier("alternative")1682 )1683 ),1684 ]);1685 assert.strictEqual(1686 removeSpaces(element.children[0].toString(this.toStringOptions)),1687 removeSpaces(`1688 <div #slotChildren style="display:contents">1689 <ng-container [ngTemplateOutlet]="dxchildren"></ng-container>1690 </div>1691 <ng-container *ngIf="!(children)">{{alternative}}</ng-container>1692 `)1693 );1694 });1695 });1696 mocha.describe("Spread Attributes on html element", function () {1697 this.beforeEach(function () {1698 generator.setContext(null);1699 generator.setContext({1700 dirname: __dirname,1701 });1702 });1703 this.afterEach(function () {1704 generator.setContext(null);1705 });1706 mocha.it("should not be in element", function () {1707 const expression = generator.createJsxSpreadAttribute(1708 generator.createIdentifier("attr")1709 );1710 assert.strictEqual(expression.toString(), "");1711 });1712 mocha.it(1713 "element with spread attribute should not generate ref attribute if it have one",1714 function () {1715 const spread = generator.createJsxSpreadAttribute(1716 generator.createIdentifier("attr")1717 );1718 const element = generator.createJsxSelfClosingElement(1719 generator.createIdentifier("input"),1720 [],1721 [1722 spread,1723 generator.createJsxAttribute(1724 generator.createIdentifier("ref"),1725 generator.createIdentifier("value")1726 ),1727 ]1728 );1729 assert.strictEqual(element.toString(), "<input #value/>");1730 const spreadAttributes = element.getSpreadAttributes();1731 assert.strictEqual(spreadAttributes.length, 1);1732 assert.strictEqual(spreadAttributes[0].expression.toString(), "attr");1733 assert.strictEqual(1734 spreadAttributes[0].refExpression.toString(),1735 "value"1736 );1737 }1738 );1739 mocha.it(1740 "element with spread attribute should generate unique ref attribute if it have no one",1741 function () {1742 const spread = generator.createJsxSpreadAttribute(1743 generator.createIdentifier("attr")1744 );1745 const element = generator.createJsxSelfClosingElement(1746 generator.createIdentifier("input"),1747 [],1748 [spread]1749 );1750 assert.strictEqual(element.toString(), "<input #_auto_ref_0/>");1751 const spreadAttributes = element.getSpreadAttributes();1752 assert.strictEqual(spreadAttributes.length, 1);1753 assert.strictEqual(spreadAttributes[0].expression.toString(), "attr");1754 assert.strictEqual(1755 spreadAttributes[0].refExpression.toString(),1756 "_auto_ref_0"1757 );1758 }1759 );1760 mocha.it(1761 "getJsxAttributes should collect attributes from all tree",1762 function () {1763 const spread = generator.createJsxSpreadAttribute(1764 generator.createIdentifier("attr")1765 );1766 const element = generator.createJsxElement(1767 generator.createJsxOpeningElement(1768 generator.createIdentifier("div"),1769 [],1770 [spread]1771 ),1772 [1773 generator.createJsxSelfClosingElement(1774 generator.createIdentifier("input"),1775 [],1776 [spread]1777 ),1778 ],1779 generator.createJsxClosingElement(generator.createIdentifier("div"))1780 );1781 assert.strictEqual(1782 element.toString(),1783 "<div #_auto_ref_0><input #_auto_ref_1/></div>"1784 );1785 const spreadAttributes = element.getSpreadAttributes();1786 assert.strictEqual(spreadAttributes.length, 2);1787 }1788 );1789 });1790 mocha.describe("Spread attribute on component", function () {1791 this.beforeEach(function () {1792 generator.setContext({1793 dirname: __dirname,1794 });1795 });1796 this.afterEach(function () {1797 generator.setContext(null);1798 });1799 mocha.it("...props - pick only props those exist in widget", function () {1800 const component = createComponent([1801 generator.createProperty(1802 [createDecorator(Decorators.OneWay)],1803 [],1804 generator.createIdentifier("p1")1805 ),1806 ]);1807 const element = generator.createJsxSelfClosingElement(1808 component._name,1809 [],1810 [1811 generator.createJsxSpreadAttribute(1812 generator.createIdentifier("props")1813 ),1814 ]1815 );1816 const p1 = generator.createProperty(1817 [createDecorator(Decorators.OneWay)],1818 [],1819 generator.createIdentifier("p1")1820 );1821 const p2 = generator.createProperty(1822 [createDecorator(Decorators.OneWay)],1823 [],1824 generator.createIdentifier("p2")1825 );1826 assert.strictEqual(1827 element.toString({1828 componentContext: "",1829 newComponentContext: "",1830 members: [p1, p2],1831 }),1832 `<dx-base-widget [p1]="p1"></dx-base-widget>`1833 );1834 });1835 mocha.it("...props, method - pick method", function () {1836 const component = createComponent([1837 generator.createProperty(1838 [createDecorator(Decorators.OneWay)],1839 [],1840 generator.createIdentifier("p1")1841 ),1842 ]);1843 const element = generator.createJsxSelfClosingElement(1844 component._name,1845 [],1846 [1847 generator.createJsxSpreadAttribute(1848 generator.createPropertyAccess(1849 generator.createIdentifier("viewModel"),1850 generator.createIdentifier("props")1851 )1852 ),1853 generator.createJsxAttribute(1854 generator.createIdentifier("p1"),1855 generator.createPropertyAccess(1856 generator.createIdentifier("viewModel"),1857 generator.createIdentifier("p1")1858 )1859 ),1860 ]1861 );1862 const p1 = generator.createProperty(1863 [createDecorator(Decorators.OneWay)],1864 [],1865 generator.createIdentifier("p1")1866 );1867 const p1Method = generator.createMethod(1868 [],1869 [],1870 undefined,1871 generator.createIdentifier("p1"),1872 undefined,1873 undefined,1874 [],1875 undefined,1876 generator.createBlock([], false)1877 );1878 p1Method.prefix = "__";1879 assert.strictEqual(1880 element.toString({1881 componentContext: "viewModel",1882 newComponentContext: "",1883 members: [p1, p1Method],1884 }),1885 `<dx-base-widget [p1]="__p1"></dx-base-widget>`1886 );1887 });1888 mocha.it(1889 "method, ...props - pick method if props is not exist",1890 function () {1891 const component = createComponent([1892 generator.createProperty(1893 [createDecorator(Decorators.OneWay)],1894 [],1895 generator.createIdentifier("p1")1896 ),1897 ]);1898 const element = generator.createJsxSelfClosingElement(1899 component._name,1900 [],1901 [1902 generator.createJsxAttribute(1903 generator.createIdentifier("p1"),1904 generator.createPropertyAccess(1905 generator.createIdentifier("viewModel"),1906 generator.createIdentifier("p1")1907 )1908 ),1909 generator.createJsxSpreadAttribute(1910 generator.createPropertyAccess(1911 generator.createIdentifier("viewModel"),1912 generator.createIdentifier("props")1913 )1914 ),1915 ]1916 );1917 const p1 = generator.createProperty(1918 [createDecorator(Decorators.OneWay)],1919 [],1920 generator.createIdentifier("p1")1921 );1922 const p1Method = generator.createMethod(1923 [],1924 [],1925 undefined,1926 generator.createIdentifier("p1"),1927 undefined,1928 undefined,1929 [],1930 undefined,1931 generator.createBlock([], false)1932 );1933 p1Method.prefix = "__";1934 assert.strictEqual(1935 element.toString({1936 componentContext: "viewModel",1937 newComponentContext: "",1938 members: [p1, p1Method],1939 }),1940 `<dx-base-widget [p1]="(p1!==undefined?p1:__p1)"></dx-base-widget>`1941 );1942 }1943 );1944 mocha.it("getter, ...props - pick getter, prop", function () {1945 const component = createComponent([1946 generator.createProperty(1947 [createDecorator(Decorators.OneWay)],1948 [],1949 generator.createIdentifier("p1")1950 ),1951 ]);1952 const element = generator.createJsxSelfClosingElement(1953 component._name,1954 [],1955 [1956 generator.createJsxAttribute(1957 generator.createIdentifier("p1"),1958 generator.createPropertyAccess(1959 generator.createIdentifier("viewModel"),1960 generator.createIdentifier("p1")1961 )1962 ),1963 generator.createJsxSpreadAttribute(1964 generator.createPropertyAccess(1965 generator.createIdentifier("viewModel"),1966 generator.createIdentifier("props")1967 )1968 ),1969 ]1970 );1971 const p1 = generator.createProperty(1972 [createDecorator(Decorators.OneWay)],1973 [],1974 generator.createIdentifier("p1")1975 );1976 const p1Method = generator.createGetAccessor(1977 [],1978 [],1979 generator.createIdentifier("p1"),1980 [],1981 undefined,1982 generator.createBlock([], false)1983 );1984 p1Method.prefix = "__";1985 assert.strictEqual(1986 element.toString({1987 componentContext: "viewModel",1988 newComponentContext: "",1989 members: [p1, p1Method],1990 }),1991 `<dx-base-widget [p1]="(p1!==undefined?p1:__p1)"></dx-base-widget>`1992 );1993 });1994 mocha.it("...props, getter - pick props,getter", function () {1995 const component = createComponent([1996 generator.createProperty(1997 [createDecorator(Decorators.OneWay)],1998 [],1999 generator.createIdentifier("p1")2000 ),2001 ]);2002 const element = generator.createJsxSelfClosingElement(2003 component._name,2004 [],2005 [2006 generator.createJsxSpreadAttribute(2007 generator.createPropertyAccess(2008 generator.createIdentifier("viewModel"),2009 generator.createIdentifier("props")2010 )2011 ),2012 generator.createJsxAttribute(2013 generator.createIdentifier("p1"),2014 generator.createPropertyAccess(2015 generator.createIdentifier("viewModel"),2016 generator.createIdentifier("p1")2017 )2018 ),2019 ]2020 );2021 const p1 = generator.createProperty(2022 [createDecorator(Decorators.OneWay)],2023 [],2024 generator.createIdentifier("p1")2025 );2026 const p1Method = generator.createGetAccessor(2027 [],2028 [],2029 generator.createIdentifier("p1"),2030 [],2031 undefined,2032 generator.createBlock([], false)2033 );2034 p1Method.prefix = "__";2035 assert.strictEqual(2036 element.toString({2037 componentContext: "viewModel",2038 newComponentContext: "",2039 members: [p1, p1Method],2040 }),2041 `<dx-base-widget [p1]="(__p1!==undefined?__p1:p1)"></dx-base-widget>`2042 );2043 });2044 mocha.it("...{...props, ...restAttributes} - pick props", function () {2045 const component = createComponent([2046 generator.createProperty(2047 [createDecorator(Decorators.OneWay)],2048 [],2049 generator.createIdentifier("p1")2050 ),2051 ]);2052 const element = generator.createJsxSelfClosingElement(2053 component._name,2054 [],2055 [2056 generator.createJsxSpreadAttribute(2057 generator.createObjectLiteral(2058 [2059 generator.createSpreadAssignment(2060 generator.createPropertyAccess(2061 generator.createIdentifier("viewModel"),2062 generator.createIdentifier("props")2063 )2064 ),2065 generator.createSpreadAssignment(2066 generator.createPropertyAccess(2067 generator.createIdentifier("viewModel"),2068 generator.createIdentifier("restAttributes")2069 )2070 ),2071 ],2072 false2073 )2074 ),2075 ]2076 );2077 const p1 = generator.createProperty(2078 [createDecorator(Decorators.OneWay)],2079 [],2080 generator.createIdentifier("p1")2081 );2082 const restAttributes = generator.createGetAccessor(2083 [],2084 [],2085 generator.createIdentifier("restAttributes"),2086 [],2087 undefined,2088 generator.createBlock([], false)2089 );2090 restAttributes.prefix = "__";2091 assert.strictEqual(2092 element.toString({2093 componentContext: "viewModel",2094 newComponentContext: "",2095 members: [p1, restAttributes],2096 }),2097 `<dx-base-widget [p1]="p1"></dx-base-widget>`2098 );2099 });2100 mocha.it("...{x: x, y}", function () {2101 const component = createComponent([2102 generator.createProperty(2103 [createDecorator(Decorators.OneWay)],2104 [],2105 generator.createIdentifier("x")2106 ),2107 generator.createProperty(2108 [createDecorator(Decorators.OneWay)],2109 [],2110 generator.createIdentifier("y")2111 ),2112 ]);2113 const element = generator.createJsxSelfClosingElement(2114 component._name,2115 [],2116 [2117 generator.createJsxSpreadAttribute(2118 generator.createObjectLiteral(2119 [2120 generator.createPropertyAssignment(2121 generator.createIdentifier("x"),2122 generator.createIdentifier("xValue")2123 ),2124 generator.createShorthandPropertyAssignment(2125 generator.createIdentifier("y")2126 ),2127 ],2128 false2129 )2130 ),2131 ]2132 );2133 assert.strictEqual(2134 removeSpaces(2135 element.toString({2136 componentContext: "viewModel",2137 newComponentContext: "",2138 members: [],2139 })2140 ),2141 removeSpaces(`<dx-base-widget [x]="xValue" [y]="y"></dx-base-widget>`)2142 );2143 });2144 });2145 mocha.describe("hasStyle", function () {2146 this.beforeEach(function () {2147 this.options = {2148 members: [],2149 hasStyle: false,2150 };2151 });2152 mocha.it("false if there is not any style attribute", function () {2153 const expression = generator.createJsxElement(2154 generator.createJsxOpeningElement(2155 generator.createIdentifier("span"),2156 undefined,2157 []2158 ),2159 [],2160 generator.createJsxClosingElement(generator.createIdentifier("span"))2161 );2162 expression.toString(this.options);2163 assert.strictEqual(this.options.hasStyle, false);2164 });2165 mocha.it("true if there is a style attribute", function () {2166 const expression = generator.createJsxElement(2167 generator.createJsxOpeningElement(2168 generator.createIdentifier("span"),2169 undefined,2170 [2171 generator.createJsxAttribute(2172 generator.createIdentifier("style"),2173 generator.createIdentifier("value")2174 ),2175 ]2176 ),2177 [],2178 generator.createJsxClosingElement(generator.createIdentifier("span"))2179 );2180 expression.toString(this.options);2181 assert.strictEqual(this.options.hasStyle, true);2182 });2183 mocha.it(2184 "true if there is a style attribute in the child element",2185 function () {2186 const expression = generator.createJsxElement(2187 generator.createJsxOpeningElement(2188 generator.createIdentifier("div"),2189 undefined,2190 []2191 ),2192 [2193 generator.createJsxElement(2194 generator.createJsxOpeningElement(2195 generator.createIdentifier("span"),2196 undefined,2197 [2198 generator.createJsxAttribute(2199 generator.createIdentifier("style"),2200 generator.createIdentifier("value")2201 ),2202 ]2203 ),2204 [],2205 generator.createJsxClosingElement(2206 generator.createIdentifier("span")2207 )2208 ),2209 ],2210 generator.createJsxClosingElement(generator.createIdentifier("div"))2211 );2212 expression.toString(this.options);2213 assert.strictEqual(this.options.hasStyle, true);2214 }2215 );2216 mocha.it(2217 "true if there is a style attribute in the child self-closing element",2218 function () {2219 const expression = generator.createJsxElement(2220 generator.createJsxOpeningElement(2221 generator.createIdentifier("div"),2222 undefined,2223 []2224 ),2225 [2226 generator.createJsxSelfClosingElement(2227 generator.createIdentifier("span"),2228 undefined,2229 [2230 generator.createJsxAttribute(2231 generator.createIdentifier("style"),2232 generator.createIdentifier("value")2233 ),2234 ]2235 ),2236 ],2237 generator.createJsxClosingElement(generator.createIdentifier("div"))2238 );2239 expression.toString(this.options);2240 assert.strictEqual(this.options.hasStyle, true);2241 }2242 );2243 });2244 mocha.it("ref", function () {2245 const expression = generator.createJsxAttribute(2246 generator.createIdentifier("ref"),2247 generator.createPropertyAccess(2248 generator.createIdentifier("viewModel"),2249 generator.createIdentifier("refName")2250 )2251 );2252 assert.strictEqual(expression.toString(), "#viewModel.refName");2253 });2254 mocha.it("ref with component context", function () {2255 const expression = generator.createJsxAttribute(2256 generator.createIdentifier("ref"),2257 generator.createPropertyAccess(2258 generator.createIdentifier("viewModel"),2259 generator.createIdentifier("refName")2260 )2261 );2262 assert.strictEqual(2263 expression.toString({2264 members: [2265 generator.createProperty(2266 [createDecorator(Decorators.Ref)],2267 [],2268 generator.createIdentifier("refName"),2269 undefined,2270 undefined,2271 undefined2272 ),2273 ],2274 componentContext: "viewModel",2275 newComponentContext: "",2276 }),2277 "#refName"2278 );2279 });2280 mocha.it("ref with component context", function () {2281 const expression = generator.createJsxAttribute(2282 generator.createIdentifier("ref"),2283 generator.createAsExpression(2284 generator.createPropertyAccess(2285 generator.createIdentifier("viewModel"),2286 generator.createIdentifier("refName")2287 ),2288 generator.createKeywordTypeNode("any")2289 )2290 );2291 assert.strictEqual(2292 expression.toString({2293 members: [2294 generator.createProperty(2295 [createDecorator(Decorators.Ref)],2296 [],2297 generator.createIdentifier("refName"),2298 undefined,2299 generator.createKeywordTypeNode("HTMLDivElement"),2300 undefined2301 ),2302 ],2303 componentContext: "viewModel",2304 newComponentContext: "",2305 }),2306 "#refName"2307 );2308 });2309 mocha.describe("slots", function () {2310 mocha.it("named slot", function () {2311 const expression = generator.createJsxElement(2312 generator.createJsxOpeningElement(2313 generator.createIdentifier("span"),2314 undefined,2315 []2316 ),2317 [2318 generator.createJsxExpression(2319 undefined,2320 generator.createPropertyAccess(2321 generator.createIdentifier("viewModel"),2322 generator.createIdentifier("name")2323 )2324 ),2325 ],2326 generator.createJsxClosingElement(generator.createIdentifier("span"))2327 );2328 const slotProperty = generator.createProperty(2329 [createDecorator("Slot")],2330 [],2331 generator.createIdentifier("name"),2332 generator.SyntaxKind.QuestionToken,2333 undefined,2334 generator.createFalse()2335 );2336 assert.strictEqual(2337 removeSpaces(2338 expression.toString({2339 members: [slotProperty],2340 componentContext: "viewModel",2341 })2342 ),2343 removeSpaces(`2344 <span >2345 <div #slotName style="display: contents">2346 <ng-container [ngTemplateOutlet]="dxname"></ng-container>2347 </div>2348 </span>`)2349 );2350 });2351 mocha.it("named slot with empty context", function () {2352 const expression = generator.createJsxElement(2353 generator.createJsxOpeningElement(2354 generator.createIdentifier("span"),2355 undefined,2356 []2357 ),2358 [2359 generator.createJsxExpression(2360 undefined,2361 generator.createPropertyAccess(2362 generator.createIdentifier("viewModel"),2363 generator.createIdentifier("name")2364 )2365 ),2366 ],2367 generator.createJsxClosingElement(generator.createIdentifier("span"))2368 );2369 const slotProperty = generator.createProperty(2370 [createDecorator("Slot")],2371 [],2372 generator.createIdentifier("name"),2373 generator.SyntaxKind.QuestionToken,2374 undefined,2375 generator.createFalse()2376 );2377 assert.strictEqual(2378 removeSpaces(2379 expression.toString({2380 members: [slotProperty],2381 componentContext: "viewModel",2382 newComponentContext: "",2383 })2384 ),2385 removeSpaces(`2386 <span>2387 <div #slotName style="display: contents">2388 <ng-container [ngTemplateOutlet]="dxname"></ng-container>2389 </div>2390 </span>`)2391 );2392 });2393 mocha.it("children slot", function () {2394 const expression = generator.createJsxElement(2395 generator.createJsxOpeningElement(2396 generator.createIdentifier("span"),2397 undefined,2398 []2399 ),2400 [2401 generator.createJsxExpression(2402 undefined,2403 generator.createPropertyAccess(2404 generator.createIdentifier("viewModel"),2405 generator.createIdentifier("children")2406 )2407 ),2408 ],2409 generator.createJsxClosingElement(generator.createIdentifier("span"))2410 );2411 const slotProperty = generator.createProperty(2412 [createDecorator("Slot")],2413 [],2414 generator.createIdentifier("children"),2415 generator.SyntaxKind.QuestionToken,2416 undefined,2417 generator.createFalse()2418 );2419 assert.strictEqual(2420 removeSpaces(2421 expression.toString({2422 members: [slotProperty],2423 })2424 ),2425 removeSpaces(`2426 <span>2427 <div #slotChildren style="display: contents">2428 <ng-container [ngTemplateOutlet]="dxchildren"></ng-container>2429 </div>2430 </span>`)2431 );2432 });2433 mocha.it("slot in svg component", function () {2434 const expression = generator.createJsxElement(2435 generator.createJsxOpeningElement(2436 generator.createIdentifier("svg"),2437 undefined,2438 []2439 ),2440 [2441 generator.createJsxExpression(2442 undefined,2443 generator.createPropertyAccess(2444 generator.createIdentifier("viewModel"),2445 generator.createIdentifier("children")2446 )2447 ),2448 ],2449 generator.createJsxClosingElement(generator.createIdentifier("svg"))2450 );2451 const slotProperty = generator.createProperty(2452 [createDecorator("Slot")],2453 [],2454 generator.createIdentifier("children"),2455 generator.SyntaxKind.QuestionToken,2456 undefined,2457 generator.createFalse()2458 );2459 assert.strictEqual(2460 removeSpaces(2461 expression.toString({2462 members: [slotProperty],2463 isSVG: true,2464 })2465 ),2466 removeSpaces(`2467 <svg:svg >2468 <svg:g #slotChildren >2469 <ng-container [ngTemplateOutlet]="dxchildren"></ng-container>2470 </svg:g>2471 </svg>`)2472 );2473 });2474 mocha.describe("Import widget.", function () {2475 this.beforeEach(function () {2476 generator.setContext({2477 dirname: __dirname,2478 });2479 generator.createImportDeclaration(2480 [],2481 [],2482 generator.createImportClause(2483 generator.createIdentifier("Widget"),2484 undefined2485 ),2486 generator.createStringLiteral(2487 "./test-cases/declarations/src/empty-component"2488 )2489 );2490 });2491 this.afterEach(function () {2492 generator.setContext(null);2493 });2494 mocha.it("<Widget></Widget> -> <dx-widget></dx-widget>", function () {2495 const element = generator.createJsxElement(2496 generator.createJsxOpeningElement(2497 generator.createIdentifier("Widget")2498 ),2499 [],2500 generator.createJsxClosingElement(2501 generator.createIdentifier("Widget")2502 )2503 );2504 assert.strictEqual(element.toString(), "<dx-widget ></dx-widget>");2505 });2506 mocha.it("<Widget/> -> <dx-widget></dx-widget>", function () {2507 const element = generator.createJsxSelfClosingElement(2508 generator.createIdentifier("Widget"),2509 []2510 );2511 assert.strictEqual(element.toString(), "<dx-widget ></dx-widget>");2512 });2513 mocha.it(2514 "import component statement should have import module",2515 function () {2516 const expression = generator.createImportDeclaration(2517 [],2518 [],2519 generator.createImportClause(2520 generator.createIdentifier("Component"),2521 undefined2522 ),2523 generator.createStringLiteral(2524 "./test-cases/declarations/src/empty-component"2525 )2526 );2527 assert.strictEqual(2528 expression.toString(),2529 `import Component,{DxWidgetModule} from "./test-cases/declarations/src/empty-component"`2530 );2531 }2532 );2533 mocha.it(2534 "import named exported component statement should have import module",2535 function () {2536 const expression = generator.createImportDeclaration(2537 undefined,2538 undefined,2539 generator.createImportClause(2540 undefined,2541 generator.createNamedImports([2542 generator.createImportSpecifier(2543 undefined,2544 generator.createIdentifier("Widget")2545 ),2546 ])2547 ),2548 generator.createStringLiteral(2549 "./test-cases/declarations/src/export-named-api-ref"2550 )2551 );2552 assert.strictEqual(2553 generator.getContext().components?.["Widget"].name,2554 "Widget"2555 );2556 assertCode(2557 expression.toString(),2558 `import {Widget, DxWidgetModule} from "./test-cases/declarations/src/export-named-api-ref"`2559 );2560 }2561 );2562 mocha.it("Event attribute should be wrapped in paren", function () {2563 generator.createClassDeclaration(2564 [createComponentDecorator({})],2565 [],2566 generator.createIdentifier("Widget"),2567 [],2568 [],2569 [2570 generator.createProperty(2571 [createDecorator(Decorators.Event)],2572 [],2573 generator.createIdentifier("event"),2574 undefined,2575 undefined,2576 undefined2577 ),2578 ]2579 );2580 const element = generator.createJsxSelfClosingElement(2581 generator.createIdentifier("Widget"),2582 [],2583 [2584 generator.createJsxAttribute(2585 generator.createIdentifier("event"),2586 generator.createIdentifier("value")2587 ),2588 ]2589 );2590 assert.strictEqual(2591 element.toString({2592 members: [],2593 }),2594 `<dx-widget (event)="value($event)"></dx-widget>`2595 );2596 });2597 mocha.it("className should not be renamed to class", function () {2598 generator.createClassDeclaration(2599 [createComponentDecorator({})],2600 [],2601 generator.createIdentifier("Widget"),2602 [],2603 [],2604 [2605 generator.createProperty(2606 [createDecorator(Decorators.OneWay)],2607 [],2608 generator.createIdentifier("className"),2609 undefined,2610 undefined,2611 undefined2612 ),2613 ]2614 );2615 const element = generator.createJsxSelfClosingElement(2616 generator.createIdentifier("Widget"),2617 [],2618 [2619 generator.createJsxAttribute(2620 generator.createIdentifier("className"),2621 generator.createIdentifier("value")2622 ),2623 ]2624 );2625 assert.strictEqual(2626 element.toString({2627 members: [],2628 }),2629 `<dx-widget [className]="value"></dx-widget>`2630 );2631 });2632 mocha.it(2633 "className should be renamed to class in children",2634 function () {2635 generator.createClassDeclaration(2636 [createComponentDecorator({})],2637 [],2638 generator.createIdentifier("Widget"),2639 [],2640 [],2641 [2642 generator.createProperty(2643 [createDecorator(Decorators.OneWay)],2644 [],2645 generator.createIdentifier("className"),2646 undefined,2647 undefined,2648 undefined2649 ),2650 ]2651 );2652 const element = generator.createJsxElement(2653 generator.createJsxOpeningElement(2654 generator.createIdentifier("Widget"),2655 [],2656 [2657 generator.createJsxAttribute(2658 generator.createIdentifier("className"),2659 generator.createIdentifier("value")2660 ),2661 ]2662 ),2663 [2664 generator.createJsxElement(2665 generator.createJsxOpeningElement(2666 generator.createIdentifier("div"),2667 [],2668 [2669 generator.createJsxAttribute(2670 generator.createIdentifier("className"),2671 generator.createStringLiteral("class-name")2672 ),2673 ]2674 ),2675 [],2676 generator.createJsxClosingElement(2677 generator.createIdentifier("div")2678 )2679 ),2680 ],2681 generator.createJsxClosingElement(2682 generator.createIdentifier("Widget")2683 )2684 );2685 assert.strictEqual(2686 element.toString({2687 members: [],2688 }),2689 `<dx-widget [className]="value"><div class="class-name"></div></dx-widget>`2690 );2691 }2692 );2693 mocha.describe("Pass slots via attribute", function () {2694 this.beforeEach(function () {2695 generator.setContext({2696 dirname: __dirname,2697 });2698 const defaultSlot = generator.createProperty(2699 [createDecorator("Slot")],2700 [],2701 generator.createIdentifier("children")2702 );2703 const namedSlot = generator.createProperty(2704 [createDecorator("Slot")],2705 [],2706 generator.createIdentifier("namedSlot")2707 );2708 generator.createClassDeclaration(2709 [createComponentDecorator({})],2710 [],2711 generator.createIdentifier("Widget"),2712 [],2713 [],2714 [defaultSlot, namedSlot]2715 );2716 });2717 this.afterEach(function () {2718 generator.setContext(null);2719 });2720 mocha.it("Self-closing element", function () {2721 const slotProperty = generator.createProperty(2722 [createDecorator("Slot")],2723 [],2724 generator.createIdentifier("children")2725 );2726 const element = generator.createJsxSelfClosingElement(2727 generator.createIdentifier("Widget"),2728 [],2729 [2730 generator.createJsxAttribute(2731 generator.createIdentifier("children"),2732 generator.createPropertyAccess(2733 generator.createIdentifier("props"),2734 generator.createIdentifier("children")2735 )2736 ),2737 ]2738 );2739 assert.strictEqual(2740 removeSpaces(2741 element.toString({2742 componentContext: "",2743 newComponentContext: "",2744 members: [slotProperty],2745 })2746 ),2747 removeSpaces(`2748 <dx-widget>2749 <div #slotChildren style="display: contents">2750 <ng-container [ngTemplateOutlet]="dxchildren"></ng-container>2751 </div>2752 </dx-widget>`)2753 );2754 });2755 mocha.it("Self-closing element with two slots", function () {2756 const slotProperty = generator.createProperty(2757 [createDecorator("Slot")],2758 [],2759 generator.createIdentifier("children")2760 );2761 const namedSlot = generator.createProperty(2762 [createDecorator("Slot")],2763 [],2764 generator.createIdentifier("namedSlot")2765 );2766 const element = generator.createJsxSelfClosingElement(2767 generator.createIdentifier("Widget"),2768 [],2769 [2770 generator.createJsxAttribute(2771 generator.createIdentifier("children"),2772 generator.createPropertyAccess(2773 generator.createIdentifier("props"),2774 generator.createIdentifier("children")2775 )2776 ),2777 generator.createJsxAttribute(2778 generator.createIdentifier("namedSlot"),2779 generator.createPropertyAccess(2780 generator.createIdentifier("props"),2781 generator.createIdentifier("namedSlot")2782 )2783 ),2784 ]2785 );2786 assert.strictEqual(2787 removeSpaces(2788 element.toString({2789 componentContext: "",2790 newComponentContext: "",2791 members: [slotProperty, namedSlot],2792 })2793 ),2794 removeSpaces(`2795 <dx-widget>2796 <div #slotChildrenstyle="display:contents">2797 <ng-container [ngTemplateOutlet]="dxchildren">2798 </ng-container>2799 </div>2800 <div #slotNamedSlot style="display:contents">2801 <ng-container[ngTemplateOutlet]="dxnamedSlot">2802 </ng-container>2803 </div>2804 </dx-widget>`)2805 );2806 });2807 mocha.it("spread props with slot", function () {2808 const slotProperty = generator.createProperty(2809 [createDecorator("Slot")],2810 [],2811 generator.createIdentifier("children")2812 );2813 const element = generator.createJsxSelfClosingElement(2814 generator.createIdentifier("Widget"),2815 [],2816 [2817 generator.createJsxSpreadAttribute(2818 generator.createPropertyAccess(2819 generator.createIdentifier(2820 generator.SyntaxKind.ThisKeyword2821 ),2822 generator.createIdentifier("props")2823 )2824 ),2825 ]2826 );2827 assert.strictEqual(2828 removeSpaces(2829 element.toString({2830 componentContext: "this",2831 newComponentContext: "",2832 members: [slotProperty],2833 })2834 ),2835 removeSpaces(`2836 <dx-widget >2837 <div #slotChildren style="display: contents">2838 <ng-container [ngTemplateOutlet]="dxchildren"></ng-container>2839 </div>2840 </dx-widget>`)2841 );2842 });2843 mocha.it("element with closing tag", function () {2844 const slotProperty = generator.createProperty(2845 [createDecorator("Slot")],2846 [],2847 generator.createIdentifier("children")2848 );2849 const element = generator.createJsxElement(2850 generator.createJsxOpeningElement(2851 generator.createIdentifier("Widget"),2852 [],2853 [2854 generator.createJsxAttribute(2855 generator.createIdentifier("children"),2856 generator.createPropertyAccess(2857 generator.createIdentifier("props"),2858 generator.createIdentifier("children")2859 )2860 ),2861 ]2862 ),2863 [],2864 generator.createJsxClosingElement(2865 generator.createIdentifier("Widget")2866 )2867 );2868 assert.strictEqual(2869 removeSpaces(2870 element.toString({2871 componentContext: "",2872 newComponentContext: "",2873 members: [slotProperty],2874 })2875 ),2876 removeSpaces(`2877 <dx-widget >2878 <div #slotChildren style="display: contents">2879 <ng-container [ngTemplateOutlet]="dxchildren"></ng-container>2880 </div>2881 </dx-widget>`)2882 );2883 });2884 });2885 });2886 });2887 mocha.describe("template", function () {2888 mocha.it("<template/> -> <ng-container>", function () {2889 const expression = generator.createJsxSelfClosingElement(2890 generator.createPropertyAccess(2891 generator.createIdentifier("viewModel"),2892 generator.createIdentifier("template")2893 ),2894 [],2895 []2896 );2897 const templateProperty = generator.createProperty(2898 [createDecorator("Template")],2899 [],2900 generator.createIdentifier("template"),2901 generator.SyntaxKind.QuestionToken,2902 undefined,2903 undefined2904 );2905 assert.strictEqual(2906 expression.toString({2907 members: [templateProperty],2908 componentContext: "viewModel",2909 newComponentContext: "",2910 }),2911 `<ng-container *ngTemplateOutlet="template"></ng-container>`2912 );2913 });2914 mocha.it(2915 "<template><template -> <ng-container></ng-container>",2916 function () {2917 const expression = generator.createJsxElement(2918 generator.createJsxOpeningElement(2919 generator.createPropertyAccess(2920 generator.createIdentifier("viewModel"),2921 generator.createIdentifier("template")2922 ),2923 [],2924 []2925 ),2926 [],2927 generator.createJsxClosingElement(2928 generator.createPropertyAccess(2929 generator.createIdentifier("viewModel"),2930 generator.createIdentifier("template")2931 )2932 )2933 );2934 const templateProperty = generator.createProperty(2935 [createDecorator("Template")],2936 [],2937 generator.createIdentifier("template"),2938 generator.SyntaxKind.QuestionToken,2939 undefined,2940 undefined2941 );2942 assert.strictEqual(2943 expression.toString({2944 members: [templateProperty],2945 componentContext: "viewModel",2946 newComponentContext: "",2947 }),2948 `<ng-container *ngTemplateOutlet="template"></ng-container>`2949 );2950 }2951 );2952 mocha.it("template attributes -> template context", function () {2953 const expression = generator.createJsxSelfClosingElement(2954 generator.createPropertyAccess(2955 generator.createIdentifier("viewModel"),2956 generator.createIdentifier("template")2957 ),2958 [],2959 [2960 generator.createJsxAttribute(2961 generator.createIdentifier("a1"),2962 generator.createStringLiteral("str")2963 ),2964 generator.createJsxAttribute(2965 generator.createIdentifier("a2"),2966 generator.createNumericLiteral("10")2967 ),2968 ]2969 );2970 const templateProperty = generator.createProperty(2971 [createDecorator("Template")],2972 [],2973 generator.createIdentifier("template"),2974 generator.SyntaxKind.QuestionToken,2975 undefined,2976 undefined2977 );2978 assert.strictEqual(2979 removeSpaces(2980 expression.toString({2981 members: [templateProperty],2982 componentContext: "viewModel",2983 newComponentContext: "",2984 })2985 ),2986 removeSpaces(2987 `<ng-container *ngTemplateOutlet="template; context:{a1: \'str\',a2: 10}"></ng-container>`2988 )2989 );2990 });2991 mocha.it(2992 "template attributes -> template context. bind method to this",2993 function () {2994 const expression = generator.createJsxSelfClosingElement(2995 generator.createPropertyAccess(2996 generator.createIdentifier("viewModel"),2997 generator.createIdentifier("template")2998 ),2999 [],3000 [3001 generator.createJsxAttribute(3002 generator.createIdentifier("m"),3003 generator.createPropertyAccess(3004 generator.createIdentifier("viewModel"),3005 generator.createIdentifier("m")3006 )3007 ),3008 ]3009 );3010 const templateProperty = generator.createProperty(3011 [createDecorator("Template")],3012 [],3013 generator.createIdentifier("template"),3014 generator.SyntaxKind.QuestionToken,3015 undefined,3016 undefined3017 );3018 const method = generator.createMethod(3019 [],3020 [],3021 undefined,3022 generator.createIdentifier("m"),3023 undefined,3024 undefined,3025 [],3026 undefined,3027 generator.createBlock([], false)3028 );3029 assert.strictEqual(3030 removeSpaces(3031 expression.toString({3032 members: [templateProperty, method],3033 componentContext: "viewModel",3034 newComponentContext: "",3035 })3036 ),3037 removeSpaces(3038 `<ng-container*ngTemplateOutlet="template;context:{m:m.bind(this)}"></ng-container>`3039 )3040 );3041 }3042 );3043 mocha.it(3044 "template attributes -> template context. Do not bind GetAccessor to this",3045 function () {3046 const expression = generator.createJsxSelfClosingElement(3047 generator.createPropertyAccess(3048 generator.createIdentifier("viewModel"),3049 generator.createIdentifier("template")3050 ),3051 [],3052 [3053 generator.createJsxAttribute(3054 generator.createIdentifier("m"),3055 generator.createPropertyAccess(3056 generator.createIdentifier("viewModel"),3057 generator.createIdentifier("m")3058 )3059 ),3060 ]3061 );3062 const templateProperty = generator.createProperty(3063 [createDecorator("Template")],3064 [],3065 generator.createIdentifier("template"),3066 generator.SyntaxKind.QuestionToken,3067 undefined,3068 undefined3069 );3070 const getter = generator.createGetAccessor(3071 [],3072 [],3073 generator.createIdentifier("m"),3074 [],3075 undefined,3076 generator.createBlock([], false)3077 );3078 assert.strictEqual(3079 removeSpaces(3080 expression.toString({3081 members: [templateProperty, getter],3082 componentContext: "viewModel",3083 newComponentContext: "",3084 })3085 ),3086 removeSpaces(3087 `<ng-container*ngTemplateOutlet="template;context:{m:m}"></ng-container>`3088 )3089 );3090 }3091 );3092 mocha.describe(3093 "Template with spread attribute -> template context",3094 function () {3095 mocha.it("template jsx spread attributes", function () {3096 const expression = generator.createJsxSelfClosingElement(3097 generator.createPropertyAccess(3098 generator.createIdentifier("viewModel"),3099 generator.createIdentifier("template")3100 ),3101 [],3102 [3103 generator.createJsxAttribute(3104 generator.createIdentifier("a1"),3105 generator.createNumericLiteral("10")3106 ),3107 generator.createJsxSpreadAttribute(3108 generator.createIdentifier("spreadContext")3109 ),3110 ]3111 );3112 const templateProperty = generator.createProperty(3113 [createDecorator("Template")],3114 [],3115 generator.createIdentifier("template"),3116 generator.SyntaxKind.QuestionToken,3117 undefined,3118 undefined3119 );3120 assert.strictEqual(3121 removeSpaces(3122 expression.toString({3123 members: [templateProperty],3124 componentContext: "viewModel",3125 newComponentContext: "",3126 })3127 ),3128 removeSpaces(3129 `<ng-container *ngTemplateOutlet="template; context:{a1: 10}"></ng-container>`3130 )3131 );3132 });3133 mocha.it("...getter", function () {3134 generator.createClassDeclaration(3135 [createDecorator(Decorators.ComponentBindings)],3136 [],3137 generator.createIdentifier("Props"),3138 [],3139 [],3140 [3141 generator.createProperty(3142 [createDecorator(Decorators.OneWay)],3143 [],3144 generator.createIdentifier("p1")3145 ),3146 generator.createProperty(3147 [createDecorator(Decorators.OneWay)],3148 [],3149 generator.createIdentifier("p2")3150 ),3151 ]3152 );3153 const expression = generator.createJsxSelfClosingElement(3154 generator.createPropertyAccess(3155 generator.createIdentifier("viewModel"),3156 generator.createIdentifier("template")3157 ),3158 [],3159 [3160 generator.createJsxSpreadAttribute(3161 generator.createPropertyAccess(3162 generator.createIdentifier("viewModel"),3163 generator.createIdentifier("spread")3164 )3165 ),3166 ]3167 );3168 const templateProperty = generator.createProperty(3169 [createDecorator("Template")],3170 [],3171 generator.createIdentifier("template")3172 );3173 const spreadGetter = generator.createGetAccessor(3174 [],3175 [],3176 generator.createIdentifier("spread"),3177 [],3178 generator.createTypeReferenceNode(3179 generator.createIdentifier("Props")3180 ),3181 generator.createBlock([], false)3182 );3183 assert.strictEqual(3184 removeSpaces(3185 expression.toString({3186 members: [templateProperty, spreadGetter],3187 componentContext: "viewModel",3188 newComponentContext: "",3189 })3190 ),3191 removeSpaces(3192 `<ng-container *ngTemplateOutlet="template; context:{p1:spread.p1,p2:spread.p2}"></ng-container>`3193 )3194 );3195 });3196 mocha.it("...getter as type", function () {3197 generator.createClassDeclaration(3198 [createDecorator(Decorators.ComponentBindings)],3199 [],3200 generator.createIdentifier("Props"),3201 [],3202 [],3203 [3204 generator.createProperty(3205 [createDecorator(Decorators.OneWay)],3206 [],3207 generator.createIdentifier("p1")3208 ),3209 generator.createProperty(3210 [createDecorator(Decorators.OneWay)],3211 [],3212 generator.createIdentifier("p2")3213 ),3214 ]3215 );3216 const expression = generator.createJsxSelfClosingElement(3217 generator.createPropertyAccess(3218 generator.createIdentifier("viewModel"),3219 generator.createIdentifier("template")3220 ),3221 [],3222 [3223 generator.createJsxSpreadAttribute(3224 generator.createAsExpression(3225 generator.createPropertyAccess(3226 generator.createIdentifier("viewModel"),3227 generator.createIdentifier("spread")3228 ),3229 generator.createTypeReferenceNode(3230 generator.createIdentifier("Props")3231 )3232 )3233 ),3234 ]3235 );3236 const templateProperty = generator.createProperty(3237 [createDecorator("Template")],3238 [],3239 generator.createIdentifier("template")3240 );3241 const spreadGetter = generator.createGetAccessor(3242 [],3243 [],3244 generator.createIdentifier("spread"),3245 [],3246 undefined,3247 generator.createBlock([], false)3248 );3249 assert.strictEqual(3250 removeSpaces(3251 expression.toString({3252 members: [templateProperty, spreadGetter],3253 componentContext: "viewModel",3254 newComponentContext: "",3255 disableTemplates: true,3256 })3257 ),3258 removeSpaces(3259 `<ng-container *ngTemplateOutlet="template; context:{p1:spread.p1,p2:spread.p2}"></ng-container>`3260 )3261 );3262 });3263 mocha.it("...{x, y}", function () {3264 const expression = generator.createJsxSelfClosingElement(3265 generator.createPropertyAccess(3266 generator.createIdentifier("viewModel"),3267 generator.createIdentifier("template")3268 ),3269 [],3270 [3271 generator.createJsxSpreadAttribute(3272 generator.createObjectLiteral(3273 [3274 generator.createPropertyAssignment(3275 generator.createIdentifier("x"),3276 generator.createIdentifier("_x")3277 ),3278 generator.createShorthandPropertyAssignment(3279 generator.createIdentifier("y")3280 ),3281 ],3282 false3283 )3284 ),3285 ]3286 );3287 const templateProperty = generator.createProperty(3288 [createDecorator("Template")],3289 [],3290 generator.createIdentifier("template")3291 );3292 assert.strictEqual(3293 removeSpaces(3294 expression.toString({3295 members: [templateProperty],3296 componentContext: "viewModel",3297 newComponentContext: "",3298 })3299 ),3300 removeSpaces(3301 `<ng-container *ngTemplateOutlet="template; context:{x:_x,y:y}"></ng-container>`3302 )3303 );3304 });3305 mocha.it("...{x, y, ...getter}", function () {3306 generator.createClassDeclaration(3307 [createDecorator(Decorators.ComponentBindings)],3308 [],3309 generator.createIdentifier("Props"),3310 [],3311 [],3312 [3313 generator.createProperty(3314 [createDecorator(Decorators.OneWay)],3315 [],3316 generator.createIdentifier("p1")3317 ),3318 generator.createProperty(3319 [createDecorator(Decorators.OneWay)],3320 [],3321 generator.createIdentifier("p2")3322 ),3323 ]3324 );3325 const expression = generator.createJsxSelfClosingElement(3326 generator.createPropertyAccess(3327 generator.createIdentifier("viewModel"),3328 generator.createIdentifier("template")3329 ),3330 [],3331 [3332 generator.createJsxSpreadAttribute(3333 generator.createObjectLiteral(3334 [3335 generator.createShorthandPropertyAssignment(3336 generator.createIdentifier("y")3337 ),3338 generator.createSpreadAssignment(3339 generator.createPropertyAccess(3340 generator.createIdentifier("viewModel"),3341 generator.createIdentifier("spread")3342 )3343 ),3344 ],3345 false3346 )3347 ),3348 ]3349 );3350 const templateProperty = generator.createProperty(3351 [createDecorator("Template")],3352 [],3353 generator.createIdentifier("template")3354 );3355 const spreadGetter = generator.createGetAccessor(3356 [],3357 [],3358 generator.createIdentifier("spread"),3359 [],3360 generator.createTypeReferenceNode(3361 generator.createIdentifier("Props")3362 ),3363 generator.createBlock([], false)3364 );3365 assert.strictEqual(3366 removeSpaces(3367 expression.toString({3368 members: [templateProperty, spreadGetter],3369 componentContext: "viewModel",3370 newComponentContext: "",3371 })3372 ),3373 removeSpaces(3374 `<ng-container *ngTemplateOutlet="template; context:{y:y, p1:spread.p1, p2:spread.p2}"></ng-container>`3375 )3376 );3377 });3378 mocha.it("...{x, y, ...restAttributes}", function () {3379 const expression = generator.createJsxSelfClosingElement(3380 generator.createPropertyAccess(3381 generator.createIdentifier("viewModel"),3382 generator.createIdentifier("template")3383 ),3384 [],3385 [3386 generator.createJsxSpreadAttribute(3387 generator.createObjectLiteral(3388 [3389 generator.createShorthandPropertyAssignment(3390 generator.createIdentifier("y")3391 ),3392 generator.createSpreadAssignment(3393 generator.createPropertyAccess(3394 generator.createIdentifier("viewModel"),3395 generator.createIdentifier("restAttributes")3396 )3397 ),3398 ],3399 false3400 )3401 ),3402 ]3403 );3404 const templateProperty = generator.createProperty(3405 [createDecorator("Template")],3406 [],3407 generator.createIdentifier("template")3408 );3409 const restAttributes = generator.createGetAccessor(3410 [],3411 [],3412 generator.createIdentifier("restAttributes"),3413 [],3414 undefined,3415 generator.createBlock([], false)3416 );3417 assert.strictEqual(3418 removeSpaces(3419 expression.toString({3420 members: [templateProperty, restAttributes],3421 componentContext: "viewModel",3422 newComponentContext: "",3423 })3424 ),3425 removeSpaces(3426 `<ng-container *ngTemplateOutlet="template; context:{y:y}"></ng-container>`3427 )3428 );3429 });3430 }3431 );3432 mocha.it("render template with condition *ngIf", function () {3433 const expression = generator.createJsxSelfClosingElement(3434 generator.createPropertyAccess(3435 generator.createIdentifier("viewModel"),3436 generator.createIdentifier("template")3437 ),3438 [],3439 [3440 generator.createJsxAttribute(3441 generator.createIdentifier("a1"),3442 generator.createStringLiteral("str")3443 ),3444 generator.createJsxAttribute(3445 generator.createIdentifier("a2"),3446 generator.createNumericLiteral("10")3447 ),3448 ]3449 );3450 expression.addAttribute(3451 new AngularDirective(3452 new Identifier("*ngIf"),3453 generator.createIdentifier("condition")3454 )3455 );3456 const templateProperty = generator.createProperty(3457 [createDecorator("Template")],3458 [],3459 generator.createIdentifier("template"),3460 generator.SyntaxKind.QuestionToken,3461 undefined,3462 undefined3463 );3464 assert.strictEqual(3465 removeSpaces(3466 expression.toString({3467 members: [templateProperty],3468 componentContext: "viewModel",3469 newComponentContext: "",3470 })3471 ),3472 removeSpaces(`<ng-container *ngIf="condition">3473 <ng-container *ngTemplateOutlet="template; context:{a1: 'str',a2: 10}"></ng-container>3474 </ng-container>`)3475 );3476 });3477 mocha.it("render slot if template is not exist", function () {3478 const templateProperty = generator.createProperty(3479 [createDecorator(Decorators.Template)],3480 [],3481 generator.createIdentifier("template")3482 );3483 const slotProperty = generator.createProperty(3484 [createDecorator(Decorators.Slot)],3485 [],3486 generator.createIdentifier("children"),3487 generator.SyntaxKind.QuestionToken3488 );3489 const expression = generator.createJsxElement(3490 generator.createJsxOpeningElement(3491 generator.createIdentifier("div"),3492 undefined,3493 []3494 ),3495 [3496 generator.createJsxExpression(3497 undefined,3498 generator.createBinary(3499 generator.createPrefix(3500 generator.SyntaxKind.ExclamationToken,3501 generator.createIdentifier("template")3502 ),3503 generator.SyntaxKind.AmpersandAmpersandToken,3504 generator.createPropertyAccess(3505 generator.createPropertyAccess(3506 generator.createIdentifier("viewModel"),3507 generator.createIdentifier("props")3508 ),3509 generator.createIdentifier("children")3510 )3511 )3512 ),3513 ],3514 generator.createJsxClosingElement(generator.createIdentifier("div"))3515 );3516 assert.strictEqual(3517 removeSpaces(3518 expression.toString({3519 members: [templateProperty, slotProperty],3520 componentContext: "viewModel",3521 newComponentContext: "",3522 })3523 ),3524 removeSpaces(`3525 <div>3526 <ng-container *ngIf="!template">3527 <div #slotChildren style="display:contents">3528 <ng-container [ngTemplateOutlet]="dxchildren">3529 </ng-container>3530 </div>3531 </ng-container>3532 </div>`)3533 );3534 });3535 mocha.describe("function->ng-template", function () {3536 this.beforeEach(function () {3537 generator.setContext({3538 path: __filename,3539 dirname: __dirname,3540 });3541 createComponent([3542 generator.createProperty(3543 [createDecorator(Decorators.Template)],3544 [],3545 generator.createIdentifier("template")3546 ),3547 ]);3548 });3549 this.afterEach(function () {3550 generator.setContext(null);3551 });3552 const createElement = (parameter?: Parameter) =>3553 generator.createJsxSelfClosingElement(3554 generator.createIdentifier("BaseWidget"),3555 undefined,3556 [3557 generator.createJsxAttribute(3558 generator.createIdentifier("template"),3559 generator.createJsxExpression(3560 undefined,3561 generator.createArrowFunction(3562 [],3563 undefined,3564 parameter ? [parameter] : [],3565 undefined,3566 generator.SyntaxKind.EqualsGreaterThanToken,3567 generator.createJsxSelfClosingElement(3568 generator.createIdentifier("div")3569 )3570 )3571 )3572 ),3573 ]3574 );3575 mocha.it("w/o parameter", function () {3576 const element = createElement();3577 assert.strictEqual(3578 removeSpaces(3579 element.toString({3580 members: [],3581 })3582 ),3583 removeSpaces(`3584 <dx-base-widget [template]="__template__generated">3585 <ng-template #__template__generated>3586 <div ></div>3587 </ng-template>3588 </dx-base-widget>3589 `)3590 );3591 });3592 mocha.it("binding pattern parameter", function () {3593 const element = createElement(3594 generator.createParameter(3595 [],3596 [],3597 undefined,3598 generator.createObjectBindingPattern([3599 generator.createBindingElement(3600 undefined,3601 undefined,3602 generator.createIdentifier("p1")3603 ),3604 generator.createBindingElement(3605 undefined,3606 generator.createIdentifier("p2"),3607 generator.createIdentifier("myP2")3608 ),3609 ]),3610 undefined3611 )3612 );3613 assert.strictEqual(3614 removeSpaces(3615 element.toString({3616 members: [],3617 })3618 ),3619 removeSpaces(`3620 <dx-base-widget [template]="__template__generated">3621 <ng-template #__template__generated let-p1="p1" let-myP2="p2">3622 <div ></div>3623 </ng-template>3624 </dx-base-widget>3625 `)3626 );3627 });3628 mocha.it("parameter with literal type node", function () {3629 const element = createElement(3630 generator.createParameter(3631 [],3632 [],3633 undefined,3634 generator.createIdentifier("props"),3635 undefined,3636 generator.createTypeLiteralNode([3637 generator.createPropertySignature(3638 [],3639 generator.createIdentifier("p1"),3640 undefined,3641 generator.createKeywordTypeNode("string")3642 ),3643 generator.createPropertySignature(3644 [],3645 generator.createIdentifier("p2"),3646 undefined,3647 generator.createKeywordTypeNode("number")3648 ),3649 ])3650 )3651 );3652 assert.strictEqual(3653 removeSpaces(3654 element.toString({3655 members: [],3656 })3657 ),3658 removeSpaces(`3659 <dx-base-widget [template]="__template__generated">3660 <ng-template #__template__generated let-p1="p1" let-p2="p2">3661 <div ></div>3662 </ng-template>3663 </dx-base-widget>3664 `)3665 );3666 });3667 mocha.it("can't parse parameter without type", function () {3668 const element = createElement(3669 generator.createParameter(3670 [],3671 [],3672 undefined,3673 generator.createIdentifier("props")3674 )3675 );3676 try {3677 removeSpaces(element.toString());3678 } catch (e) {3679 assert.strictEqual(3680 e,3681 "Can't convert function parameter props into template parameter: Use BindingPattern or TypeLiteralNode"3682 );3683 }3684 });3685 });3686 });3687 mocha.describe("Parse Map function", function () {3688 mocha.it(".map((item)=><div>) -> *ngFor", function () {3689 const expression = generator.createJsxElement(3690 generator.createJsxOpeningElement(3691 generator.createIdentifier("div"),3692 undefined,3693 []3694 ),3695 [3696 generator.createJsxExpression(3697 undefined,3698 generator.createCall(3699 generator.createPropertyAccess(3700 generator.createPropertyAccess(3701 generator.createIdentifier("viewModel"),3702 generator.createIdentifier("items")3703 ),3704 generator.createIdentifier("map")3705 ),3706 undefined,3707 [3708 generator.createArrowFunction(3709 undefined,3710 undefined,3711 [3712 generator.createParameter(3713 undefined,3714 undefined,3715 undefined,3716 generator.createIdentifier("items"),3717 undefined,3718 undefined,3719 undefined3720 ),3721 ],3722 undefined,3723 generator.createToken(3724 generator.SyntaxKind.EqualsGreaterThanToken3725 ),3726 generator.createJsxElement(3727 generator.createJsxOpeningElement(3728 generator.createIdentifier("div"),3729 undefined,3730 generator.createJsxAttributes([])3731 ),3732 [],3733 generator.createJsxClosingElement(3734 generator.createIdentifier("div")3735 )3736 )3737 ),3738 ]3739 )3740 ),3741 ],3742 generator.createJsxClosingElement(generator.createIdentifier("div"))3743 );3744 assert.strictEqual(3745 expression.children[0].toString(),3746 `<ng-container *ngFor="let items of viewModel.items"><div ></div></ng-container>`3747 );3748 });3749 mocha.it(".map((item)=>item) -> *ngFor", function () {3750 const expression = generator.createJsxElement(3751 generator.createJsxOpeningElement(3752 generator.createIdentifier("div"),3753 undefined,3754 []3755 ),3756 [3757 generator.createJsxExpression(3758 undefined,3759 generator.createCall(3760 generator.createPropertyAccess(3761 generator.createPropertyAccess(3762 generator.createIdentifier("viewModel"),3763 generator.createIdentifier("items")3764 ),3765 generator.createIdentifier("map")3766 ),3767 undefined,3768 [3769 generator.createArrowFunction(3770 undefined,3771 undefined,3772 [3773 generator.createParameter(3774 undefined,3775 undefined,3776 undefined,3777 generator.createIdentifier("items"),3778 undefined,3779 undefined,3780 undefined3781 ),3782 ],3783 undefined,3784 generator.createToken(3785 generator.SyntaxKind.EqualsGreaterThanToken3786 ),3787 generator.createIdentifier("items")3788 ),3789 ]3790 )3791 ),3792 ],3793 generator.createJsxClosingElement(generator.createIdentifier("div"))3794 );3795 assert.strictEqual(3796 expression.children[0].toString(),3797 `<ng-container *ngFor="let items of viewModel.items">{{items}}</ng-container>`3798 );3799 });3800 mocha.it(".map((item, index)=><div>) -> *ngFor", function () {3801 const expression = generator.createJsxElement(3802 generator.createJsxOpeningElement(3803 generator.createIdentifier("div"),3804 undefined,3805 []3806 ),3807 [3808 generator.createJsxExpression(3809 undefined,3810 generator.createCall(3811 generator.createPropertyAccess(3812 generator.createPropertyAccess(3813 generator.createIdentifier("viewModel"),3814 generator.createIdentifier("items")3815 ),3816 generator.createIdentifier("map")3817 ),3818 undefined,3819 [3820 generator.createArrowFunction(3821 undefined,3822 undefined,3823 [3824 generator.createParameter(3825 undefined,3826 undefined,3827 undefined,3828 generator.createIdentifier("items"),3829 undefined,3830 undefined,3831 undefined3832 ),3833 generator.createParameter(3834 undefined,3835 undefined,3836 undefined,3837 generator.createIdentifier("i"),3838 undefined,3839 undefined,3840 undefined3841 ),3842 ],3843 undefined,3844 generator.createToken(3845 generator.SyntaxKind.EqualsGreaterThanToken3846 ),3847 generator.createJsxElement(3848 generator.createJsxOpeningElement(3849 generator.createIdentifier("div"),3850 undefined,3851 generator.createJsxAttributes([])3852 ),3853 [],3854 generator.createJsxClosingElement(3855 generator.createIdentifier("div")3856 )3857 )3858 ),3859 ]3860 )3861 ),3862 ],3863 generator.createJsxClosingElement(generator.createIdentifier("div"))3864 );3865 assert.strictEqual(3866 expression.children[0].toString(),3867 `<ng-container *ngFor="let items of viewModel.items;index as i"><div ></div></ng-container>`3868 );3869 });3870 mocha.it("key attribute should be ignored", function () {3871 const expression = generator.createJsxAttribute(3872 generator.createIdentifier("key"),3873 generator.createPropertyAccess(3874 generator.createIdentifier("item"),3875 generator.createIdentifier("id")3876 )3877 );3878 assert.strictEqual(expression.toString(), "");3879 });3880 mocha.it(3881 "map with key attribute should generate trackBy function",3882 function () {3883 const expression = generator.createJsxElement(3884 generator.createJsxOpeningElement(3885 generator.createIdentifier("div"),3886 undefined,3887 []3888 ),3889 [3890 generator.createJsxExpression(3891 undefined,3892 generator.createCall(3893 generator.createPropertyAccess(3894 generator.createPropertyAccess(3895 generator.createIdentifier("viewModel"),3896 generator.createIdentifier("items")3897 ),3898 generator.createIdentifier("map")3899 ),3900 undefined,3901 [3902 generator.createArrowFunction(3903 undefined,3904 undefined,3905 [3906 generator.createParameter(3907 undefined,3908 undefined,3909 undefined,3910 generator.createIdentifier("item"),3911 undefined,3912 undefined,3913 undefined3914 ),3915 ],3916 undefined,3917 generator.createToken(3918 generator.SyntaxKind.EqualsGreaterThanToken3919 ),3920 generator.createJsxElement(3921 generator.createJsxOpeningElement(3922 generator.createIdentifier("div"),3923 undefined,3924 generator.createJsxAttributes([3925 generator.createJsxAttribute(3926 generator.createIdentifier("key"),3927 generator.createPropertyAccess(3928 generator.createIdentifier("item"),3929 generator.createIdentifier("id")3930 )3931 ),3932 ])3933 ),3934 [],3935 generator.createJsxClosingElement(3936 generator.createIdentifier("div")3937 )3938 )3939 ),3940 ]3941 )3942 ),3943 ],3944 generator.createJsxClosingElement(generator.createIdentifier("div"))3945 );3946 const options: toStringOptions = {3947 members: [],3948 };3949 assert.strictEqual(3950 expression.children[0].toString(options),3951 `<ng-container *ngFor="let item of viewModel.items;trackBy: _trackBy_viewModel_items_0"><div ></div></ng-container>`3952 );3953 const trackByAttrs = options.trackBy!;3954 assert.strictEqual(trackByAttrs.length, 1);3955 assert.strictEqual(trackByAttrs[0].toString(), "");3956 assert.strictEqual(3957 getResult(trackByAttrs[0].getTrackByDeclaration()),3958 getResult(`_trackBy_viewModel_items_0(_index: number, item: any){3959 return item.id;3960 }`)3961 );3962 }3963 );3964 mocha.it("generate trackByName from complex expression", function () {3965 const expression = generator.createJsxElement(3966 generator.createJsxOpeningElement(3967 generator.createIdentifier("div"),3968 undefined,3969 []3970 ),3971 [3972 generator.createJsxExpression(3973 undefined,3974 generator.createCall(3975 generator.createPropertyAccess(3976 generator.createParen(3977 generator.createBinary(3978 generator.createPropertyAccess(3979 generator.createIdentifier("viewModel"),3980 generator.createIdentifier("items")3981 ),3982 "||",3983 generator.createArrayLiteral([], false)3984 )3985 ),3986 generator.createIdentifier("map")3987 ),3988 undefined,3989 [3990 generator.createArrowFunction(3991 undefined,3992 undefined,3993 [3994 generator.createParameter(3995 undefined,3996 undefined,3997 undefined,3998 generator.createIdentifier("item"),3999 undefined,4000 undefined,4001 undefined4002 ),4003 ],4004 undefined,4005 generator.createToken(4006 generator.SyntaxKind.EqualsGreaterThanToken4007 ),4008 generator.createJsxElement(4009 generator.createJsxOpeningElement(4010 generator.createIdentifier("div"),4011 undefined,4012 generator.createJsxAttributes([4013 generator.createJsxAttribute(4014 generator.createIdentifier("key"),4015 generator.createPropertyAccess(4016 generator.createIdentifier("item"),4017 generator.createIdentifier("id")4018 )4019 ),4020 ])4021 ),4022 [],4023 generator.createJsxClosingElement(4024 generator.createIdentifier("div")4025 )4026 )4027 ),4028 ]4029 )4030 ),4031 ],4032 generator.createJsxClosingElement(generator.createIdentifier("div"))4033 );4034 const options: toStringOptions = {4035 members: [],4036 };4037 assert.strictEqual(4038 expression.children[0].toString(options),4039 `<ng-container *ngFor="let item of (viewModel.items || []);trackBy: _trackBy_viewModel_items_0"><div ></div></ng-container>`4040 );4041 const trackByAttrs = options.trackBy!;4042 assert.strictEqual(trackByAttrs.length, 1);4043 assert.strictEqual(trackByAttrs[0].toString(), "");4044 assert.strictEqual(4045 getResult(trackByAttrs[0].getTrackByDeclaration()),4046 getResult(`_trackBy_viewModel_items_0(_index: number, item: any){4047 return item.id;4048 }`)4049 );4050 });4051 mocha.it("map - can use prop in key", function () {4052 const expression = generator.createJsxElement(4053 generator.createJsxOpeningElement(4054 generator.createIdentifier("div"),4055 undefined,4056 []4057 ),4058 [4059 generator.createJsxExpression(4060 undefined,4061 generator.createCall(4062 generator.createPropertyAccess(4063 generator.createPropertyAccess(4064 generator.createIdentifier("viewModel"),4065 generator.createIdentifier("items")4066 ),4067 generator.createIdentifier("map")4068 ),4069 undefined,4070 [4071 generator.createArrowFunction(4072 undefined,4073 undefined,4074 [4075 generator.createParameter(4076 undefined,4077 undefined,4078 undefined,4079 generator.createIdentifier("item"),4080 undefined,4081 undefined,4082 undefined4083 ),4084 ],4085 undefined,4086 generator.createToken(4087 generator.SyntaxKind.EqualsGreaterThanToken4088 ),4089 generator.createJsxElement(4090 generator.createJsxOpeningElement(4091 generator.createIdentifier("div"),4092 undefined,4093 generator.createJsxAttributes([4094 generator.createJsxAttribute(4095 generator.createIdentifier("key"),4096 generator.createElementAccess(4097 generator.createIdentifier("item"),4098 generator.createPropertyAccess(4099 generator.createPropertyAccess(4100 generator.createIdentifier("viewModel"),4101 generator.createIdentifier("props")4102 ),4103 generator.createIdentifier("keyExpr")4104 )4105 )4106 ),4107 ])4108 ),4109 [],4110 generator.createJsxClosingElement(4111 generator.createIdentifier("div")4112 )4113 )4114 ),4115 ]4116 )4117 ),4118 ],4119 generator.createJsxClosingElement(generator.createIdentifier("div"))4120 );4121 const keyExpr = generator.createProperty(4122 [createDecorator(Decorators.OneWay)],4123 undefined,4124 generator.createIdentifier("keyExpr")4125 );4126 const options: toStringOptions = {4127 members: [keyExpr],4128 componentContext: "viewModel",4129 newComponentContext: "viewModel",4130 };4131 assert.strictEqual(4132 expression.children[0].toString(options),4133 `<ng-container *ngFor="let item of viewModel.items;trackBy: _trackBy_viewModel_items_0"><div ></div></ng-container>`4134 );4135 const trackByAttrs = options.trackBy!;4136 assert.strictEqual(trackByAttrs.length, 1);4137 assert.strictEqual(trackByAttrs[0].toString(), "");4138 assert.strictEqual(4139 getResult(trackByAttrs[0].getTrackByDeclaration()),4140 getResult(`_trackBy_viewModel_items_0(_index: number, item: any){4141 return item[this.keyExpr];4142 }`)4143 );4144 });4145 mocha.it("map inside an other map", function () {4146 const insideExpression = generator.createCall(4147 generator.createPropertyAccess(4148 generator.createIdentifier("item"),4149 generator.createIdentifier("map")4150 ),4151 undefined,4152 [4153 generator.createArrowFunction(4154 undefined,4155 undefined,4156 [4157 generator.createParameter(4158 undefined,4159 undefined,4160 undefined,4161 generator.createIdentifier("_"),4162 undefined,4163 undefined,4164 undefined4165 ),4166 generator.createParameter(4167 undefined,4168 undefined,4169 undefined,4170 generator.createIdentifier("i"),4171 undefined,4172 undefined,4173 undefined4174 ),4175 ],4176 undefined,4177 generator.createToken(4178 generator.SyntaxKind.EqualsGreaterThanToken4179 ),4180 generator.createJsxElement(4181 generator.createJsxOpeningElement(4182 generator.createIdentifier("div"),4183 undefined,4184 generator.createJsxAttributes([4185 generator.createJsxAttribute(4186 generator.createIdentifier("key"),4187 generator.createIdentifier("i")4188 ),4189 ])4190 ),4191 [],4192 generator.createJsxClosingElement(4193 generator.createIdentifier("div")4194 )4195 )4196 ),4197 ]4198 );4199 const expression = generator.createJsxElement(4200 generator.createJsxOpeningElement(4201 generator.createIdentifier("div"),4202 undefined,4203 []4204 ),4205 [4206 generator.createJsxExpression(4207 undefined,4208 generator.createCall(4209 generator.createPropertyAccess(4210 generator.createPropertyAccess(4211 generator.createIdentifier("viewModel"),4212 generator.createIdentifier("items")4213 ),4214 generator.createIdentifier("map")4215 ),4216 undefined,4217 [4218 generator.createArrowFunction(4219 undefined,4220 undefined,4221 [4222 generator.createParameter(4223 undefined,4224 undefined,4225 undefined,4226 generator.createIdentifier("item"),4227 undefined,4228 undefined,4229 undefined4230 ),4231 ],4232 undefined,4233 generator.createToken(4234 generator.SyntaxKind.EqualsGreaterThanToken4235 ),4236 generator.createJsxElement(4237 generator.createJsxOpeningElement(4238 generator.createIdentifier("div"),4239 undefined,4240 generator.createJsxAttributes([4241 generator.createJsxAttribute(4242 generator.createIdentifier("key"),4243 generator.createPropertyAccess(4244 generator.createIdentifier("item"),4245 generator.createIdentifier("id")4246 )4247 ),4248 ])4249 ),4250 [4251 generator.createJsxExpression(4252 undefined,4253 insideExpression4254 ),4255 ],4256 generator.createJsxClosingElement(4257 generator.createIdentifier("div")4258 )4259 )4260 ),4261 ]4262 )4263 ),4264 ],4265 generator.createJsxClosingElement(generator.createIdentifier("div"))4266 ).children[0] as JsxExpression;4267 const options: toStringOptions = {4268 members: [],4269 };4270 assert.strictEqual(4271 expression.toString(options),4272 `<ng-container *ngFor="let item of viewModel.items;trackBy: _trackBy_viewModel_items_1"><div ><ng-container *ngFor="let _ of item;index as i;trackBy: _trackBy_item_0"><div ></div></ng-container></div></ng-container>`4273 );4274 const trackByAttrs = options.trackBy!;4275 assert.strictEqual(trackByAttrs.length, 2);4276 assert.strictEqual(4277 getResult(trackByAttrs[1].getTrackByDeclaration()),4278 getResult(`_trackBy_viewModel_items_1(_index: number, item: any){4279 return item.id;4280 }`),4281 "external map trackBy function"4282 );4283 assert.strictEqual(4284 getResult(trackByAttrs[0].getTrackByDeclaration()),4285 getResult(`_trackBy_item_0(i: number, _: any){4286 return i;4287 }`),4288 "internal map trackBy function"4289 );4290 });4291 mocha.it("m.map(a=>a.map()=><div>)", function () {4292 const insideExpression = generator.createCall(4293 generator.createPropertyAccess(4294 generator.createIdentifier("item"),4295 generator.createIdentifier("map")4296 ),4297 undefined,4298 [4299 generator.createArrowFunction(4300 undefined,4301 undefined,4302 [4303 generator.createParameter(4304 undefined,4305 undefined,4306 undefined,4307 generator.createIdentifier("_"),4308 undefined,4309 undefined,4310 undefined4311 ),4312 generator.createParameter(4313 undefined,4314 undefined,4315 undefined,4316 generator.createIdentifier("i"),4317 undefined,4318 undefined,4319 undefined4320 ),4321 ],4322 undefined,4323 generator.createToken(4324 generator.SyntaxKind.EqualsGreaterThanToken4325 ),4326 generator.createJsxElement(4327 generator.createJsxOpeningElement(4328 generator.createIdentifier("div"),4329 undefined,4330 generator.createJsxAttributes([4331 generator.createJsxAttribute(4332 generator.createIdentifier("key"),4333 generator.createIdentifier("i")4334 ),4335 ])4336 ),4337 [],4338 generator.createJsxClosingElement(4339 generator.createIdentifier("div")4340 )4341 )4342 ),4343 ]4344 );4345 const expression = generator.createJsxElement(4346 generator.createJsxOpeningElement(4347 generator.createIdentifier("div"),4348 undefined,4349 []4350 ),4351 [4352 generator.createJsxExpression(4353 undefined,4354 generator.createCall(4355 generator.createPropertyAccess(4356 generator.createPropertyAccess(4357 generator.createIdentifier("viewModel"),4358 generator.createIdentifier("items")4359 ),4360 generator.createIdentifier("map")4361 ),4362 undefined,4363 [4364 generator.createArrowFunction(4365 undefined,4366 undefined,4367 [4368 generator.createParameter(4369 undefined,4370 undefined,4371 undefined,4372 generator.createIdentifier("item"),4373 undefined,4374 undefined,4375 undefined4376 ),4377 ],4378 undefined,4379 generator.createToken(4380 generator.SyntaxKind.EqualsGreaterThanToken4381 ),4382 insideExpression4383 ),4384 ]4385 )4386 ),4387 ],4388 generator.createJsxClosingElement(generator.createIdentifier("div"))4389 ).children[0] as JsxExpression;4390 const options: toStringOptions = {4391 members: [],4392 };4393 assert.strictEqual(4394 removeSpaces(expression.toString(options)),4395 removeSpaces(`4396 <ng-container *ngFor="let item of viewModel.items">4397 <ng-container *ngFor="let _ of item;index as i;trackBy: _trackBy_item_0">4398 <div ></div>4399 </ng-container>4400 </ng-container>`)4401 );4402 const trackByAttrs = options.trackBy!;4403 assert.strictEqual(trackByAttrs.length, 1);4404 assert.strictEqual(4405 getResult(trackByAttrs[0].getTrackByDeclaration()),4406 getResult(`_trackBy_item_0(i: number, _: any){4407 return i;4408 }`),4409 "internal map trackBy function"4410 );4411 });4412 mocha.it("map with conditional rendering", function () {4413 const expression = generator.createJsxElement(4414 generator.createJsxOpeningElement(4415 generator.createIdentifier("div"),4416 undefined,4417 []4418 ),4419 [4420 generator.createJsxExpression(4421 undefined,4422 generator.createCall(4423 generator.createPropertyAccess(4424 generator.createPropertyAccess(4425 generator.createIdentifier("viewModel"),4426 generator.createIdentifier("items")4427 ),4428 generator.createIdentifier("map")4429 ),4430 undefined,4431 [4432 generator.createArrowFunction(4433 undefined,4434 undefined,4435 [4436 generator.createParameter(4437 undefined,4438 undefined,4439 undefined,4440 generator.createIdentifier("item"),4441 undefined,4442 undefined,4443 undefined4444 ),4445 ],4446 undefined,4447 generator.createToken(4448 generator.SyntaxKind.EqualsGreaterThanToken4449 ),4450 generator.createConditional(4451 generator.createIdentifier("condition"),4452 generator.createJsxElement(4453 generator.createJsxOpeningElement(4454 generator.createIdentifier("div"),4455 undefined,4456 generator.createJsxAttributes([4457 generator.createJsxAttribute(4458 generator.createIdentifier("key"),4459 generator.createPropertyAccess(4460 generator.createIdentifier("item"),4461 generator.createIdentifier("id")4462 )4463 ),4464 ])4465 ),4466 [],4467 generator.createJsxClosingElement(4468 generator.createIdentifier("div")4469 )4470 ),4471 generator.createStringLiteral("else")4472 )4473 ),4474 ]4475 )4476 ),4477 ],4478 generator.createJsxClosingElement(generator.createIdentifier("div"))4479 );4480 const options: toStringOptions = {4481 members: [],4482 };4483 assert.strictEqual(4484 removeSpaces(expression.children[0].toString(options)),4485 removeSpaces(`<ng-container *ngFor="let item of viewModel.items;trackBy: _trackBy_viewModel_items_0">4486 <div *ngIf="condition"></div>4487 <ng-container *ngIf="!(condition)">else</ng-container>4488 </ng-container>`)4489 );4490 const trackByAttrs = options.trackBy!;4491 assert.strictEqual(trackByAttrs.length, 1);4492 assert.strictEqual(trackByAttrs[0].toString(), "");4493 assert.strictEqual(4494 getResult(trackByAttrs[0].getTrackByDeclaration()),4495 getResult(`_trackBy_viewModel_items_0(_index: number, item: any){4496 return item.id;4497 }`)4498 );4499 });4500 mocha.it("Not function in the map", function () {4501 const expression = generator.createJsxExpression(4502 undefined,4503 generator.createCall(4504 generator.createPropertyAccess(4505 generator.createPropertyAccess(4506 generator.createIdentifier("viewModel"),4507 generator.createIdentifier("items")4508 ),4509 generator.createIdentifier("map")4510 ),4511 undefined,4512 [generator.createNull()]4513 )4514 );4515 assert.strictEqual(expression.toString(), `viewModel.items.map(null)`);4516 });4517 mocha.it("Parse map with destruction", function () {4518 const expression = generator.createJsxElement(4519 generator.createJsxOpeningElement(4520 generator.createIdentifier("div"),4521 undefined,4522 []4523 ),4524 [4525 generator.createJsxExpression(4526 undefined,4527 generator.createCall(4528 generator.createPropertyAccess(4529 generator.createPropertyAccess(4530 generator.createIdentifier("viewModel"),4531 generator.createIdentifier("items")4532 ),4533 generator.createIdentifier("map")4534 ),4535 undefined,4536 [4537 generator.createArrowFunction(4538 undefined,4539 undefined,4540 [4541 generator.createParameter(4542 undefined,4543 undefined,4544 undefined,4545 generator.createObjectBindingPattern([4546 generator.createBindingElement(4547 undefined,4548 undefined,4549 generator.createIdentifier("p1")4550 ),4551 generator.createBindingElement(4552 undefined,4553 undefined,4554 generator.createIdentifier("p2")4555 ),4556 ]),4557 undefined,4558 undefined,4559 undefined4560 ),4561 ],4562 undefined,4563 generator.createToken(4564 generator.SyntaxKind.EqualsGreaterThanToken4565 ),4566 generator.createJsxElement(4567 generator.createJsxOpeningElement(4568 generator.createIdentifier("div"),4569 undefined,4570 generator.createJsxAttributes([])4571 ),4572 [4573 generator.createJsxExpression(4574 undefined,4575 generator.createIdentifier("p1")4576 ),4577 generator.createJsxExpression(4578 undefined,4579 generator.createIdentifier("p2")4580 ),4581 ],4582 generator.createJsxClosingElement(4583 generator.createIdentifier("div")4584 )4585 )4586 ),4587 ]4588 )4589 ),4590 ],4591 generator.createJsxClosingElement(generator.createIdentifier("div"))4592 );4593 assert.strictEqual(4594 removeSpaces(expression.children[0].toString()),4595 removeSpaces(`<ng-container *ngFor="let item_0 of viewModel.items">4596 <div>4597 {{item_0.p1}}4598 {{item_0.p2}}4599 </div>4600 </ng-container>`)4601 );4602 });4603 });4604 mocha.describe("View Function", function () {4605 this.beforeEach(function () {4606 generator.setContext({});4607 this.block = generator.createBlock(4608 [4609 generator.createReturn(4610 generator.createJsxSelfClosingElement(4611 generator.createIdentifier("div")4612 )4613 ),4614 ],4615 false4616 );4617 });4618 this.afterEach(function () {4619 generator.setContext(null);4620 });4621 mocha.it(4622 "Function that returns JSX can be converted to template",4623 function () {4624 const expression = generator.createFunctionDeclaration(4625 [],4626 [],4627 "",4628 generator.createIdentifier("View"),4629 [],4630 [],4631 undefined,4632 this.block4633 );4634 assert.strictEqual(expression.toString(), "");4635 assert.strictEqual(expression.getTemplate(), "<div ></div>");4636 }4637 );4638 mocha.it("Function without return statement", function () {4639 const expression = generator.createFunctionDeclaration(4640 [],4641 [],4642 "",4643 generator.createIdentifier("View"),4644 [],4645 [],4646 undefined,4647 generator.createBlock([], false)4648 );4649 assert.strictEqual(expression.getTemplate(), "");4650 });4651 mocha.it("Rename viewModel identifier", function () {4652 const expression = generator.createFunctionDeclaration(4653 [],4654 [],4655 "",4656 generator.createIdentifier("View"),4657 [],4658 [4659 generator.createParameter(4660 [],4661 [],4662 undefined,4663 generator.createIdentifier("passedViewModel"),4664 undefined,4665 undefined,4666 undefined4667 ),4668 ],4669 undefined,4670 generator.createBlock(4671 [4672 generator.createReturn(4673 generator.createJsxElement(4674 generator.createJsxOpeningElement(4675 generator.createIdentifier("span"),4676 undefined,4677 generator.createJsxAttributes([4678 generator.createJsxAttribute(4679 generator.createIdentifier("attr"),4680 generator.createPropertyAccess(4681 generator.createIdentifier("passedViewModel"),4682 generator.createIdentifier("value")4683 )4684 ),4685 ])4686 ),4687 [4688 generator.createJsxExpression(4689 undefined,4690 generator.createPropertyAccess(4691 generator.createIdentifier("passedViewModel"),4692 generator.createIdentifier("text")4693 )4694 ),4695 ],4696 generator.createJsxClosingElement(4697 generator.createIdentifier("span")4698 )4699 )4700 ),4701 ],4702 false4703 )4704 );4705 assert.strictEqual(4706 expression.getTemplate({4707 members: [],4708 newComponentContext: "_viewModel",4709 }),4710 `<span [attr]="_viewModel.value">{{_viewModel.text}}</span>`4711 );4712 });4713 mocha.it("Function without JSX is generated", function () {4714 const expression = generator.createFunctionDeclaration(4715 [],4716 [],4717 "",4718 generator.createIdentifier("View"),4719 [],4720 [],4721 undefined,4722 generator.createBlock([], false)4723 );4724 assert.strictEqual(4725 getResult(expression.toString()),4726 getResult("function View(){}")4727 );4728 assert.strictEqual(expression.getTemplate(), "");4729 });4730 mocha.it("Arrow function JSX can be converted to template", function () {4731 const expression = generator.createArrowFunction(4732 [],4733 [],4734 [],4735 undefined,4736 generator.SyntaxKind.GreaterThanToken,4737 generator.createJsxSelfClosingElement(4738 generator.createIdentifier("div")4739 )4740 );4741 assert.strictEqual(expression.isJsx(), true);4742 assert.strictEqual(expression.getTemplate(), "<div ></div>");4743 assert.strictEqual(expression.toString(), "");4744 });4745 mocha.it("template generation if jsx is wrapped into paren", function () {4746 const expression = generator.createArrowFunction(4747 [],4748 [],4749 [],4750 undefined,4751 generator.SyntaxKind.GreaterThanToken,4752 generator.createParen(4753 generator.createJsxSelfClosingElement(4754 generator.createIdentifier("div")4755 )4756 )4757 );4758 assert.strictEqual(expression.isJsx(), true);4759 assert.strictEqual(expression.getTemplate(), "<div ></div>");4760 assert.strictEqual(expression.toString(), "");4761 });4762 mocha.it(4763 "Arrow function without JSX behaves as usual function",4764 function () {4765 const expression = generator.createArrowFunction(4766 [],4767 [],4768 [],4769 undefined,4770 generator.SyntaxKind.EqualsGreaterThanToken,4771 generator.createTrue()4772 );4773 assert.strictEqual(expression.isJsx(), false);4774 assert.strictEqual(expression.getTemplate(), "{{true}}");4775 assert.strictEqual(4776 getResult(expression.toString()),4777 getResult("()=>true")4778 );4779 }4780 );4781 mocha.it("Add arrow function in context", function () {4782 const functionDeclaration = generator.createArrowFunction(4783 [],4784 [],4785 [],4786 undefined,4787 generator.SyntaxKind.EqualsGreaterThanToken,4788 this.block4789 );4790 const expression = generator.createVariableStatement(4791 [generator.SyntaxKind.ExportKeyword],4792 generator.createVariableDeclarationList(4793 [4794 generator.createVariableDeclaration(4795 generator.createIdentifier("viewFunction"),4796 undefined,4797 functionDeclaration4798 ),4799 ],4800 generator.SyntaxKind.ConstKeyword4801 )4802 );4803 assert.strictEqual(4804 generator.getContext().viewFunctions!["viewFunction"],4805 functionDeclaration4806 );4807 assert.strictEqual(expression.toString(), "");4808 });4809 mocha.it(4810 "Declaration list with jsx and noJsx - skip only jsx variables",4811 function () {4812 const functionDeclaration = generator.createArrowFunction(4813 [],4814 [],4815 [],4816 undefined,4817 generator.SyntaxKind.EqualsGreaterThanToken,4818 this.block4819 );4820 const expression = generator.createVariableDeclarationList(4821 [4822 generator.createVariableDeclaration(4823 generator.createIdentifier("viewFunction"),4824 undefined,4825 functionDeclaration4826 ),4827 generator.createVariableDeclaration(4828 generator.createIdentifier("a"),4829 undefined,4830 generator.createNumericLiteral("10")4831 ),4832 ],4833 generator.SyntaxKind.ConstKeyword4834 );4835 assert.strictEqual(expression.toString(), "const a=10");4836 }4837 );4838 mocha.it("Can use variables in view function", function () {4839 const block = generator.createBlock(4840 [4841 generator.createVariableStatement(4842 [],4843 generator.createVariableDeclarationList(4844 [4845 generator.createVariableDeclaration(4846 generator.createIdentifier("v"),4847 undefined,4848 generator.createNumericLiteral("10")4849 ),4850 ],4851 generator.SyntaxKind.ConstKeyword4852 )4853 ),4854 generator.createReturn(4855 generator.createJsxSelfClosingElement(4856 generator.createIdentifier("div"),4857 undefined,4858 [4859 generator.createJsxAttribute(4860 generator.createIdentifier("v"),4861 generator.createIdentifier("v")4862 ),4863 ]4864 )4865 ),4866 ],4867 false4868 );4869 const expression = generator.createFunctionDeclaration(4870 [],4871 [],4872 "",4873 generator.createIdentifier("View"),4874 [],4875 [],4876 undefined,4877 block4878 );4879 assert.strictEqual(expression.toString(), "");4880 assert.strictEqual(4881 expression.getTemplate({4882 members: [],4883 }),4884 `<div [v]="10"></div>`4885 );4886 });4887 mocha.it("Skip type casting in view", function () {4888 const block = generator.createBlock(4889 [4890 generator.createReturn(4891 generator.createJsxSelfClosingElement(4892 generator.createIdentifier("div"),4893 undefined,4894 [4895 generator.createJsxAttribute(4896 generator.createIdentifier("v"),4897 generator.createAsExpression(4898 generator.createIdentifier("value"),4899 generator.createKeywordTypeNode("number")4900 )4901 ),4902 ]4903 )4904 ),4905 ],4906 false4907 );4908 const expression = generator.createFunctionDeclaration(4909 [],4910 [],4911 "",4912 generator.createIdentifier("View"),4913 [],4914 [],4915 undefined,4916 block4917 );4918 assert.strictEqual(4919 expression.getTemplate({4920 members: [],4921 }),4922 `<div [v]="value"></div>`4923 );4924 });4925 mocha.it("Can decomposite component", function () {4926 const block = generator.createBlock(4927 [4928 generator.createReturn(4929 generator.createJsxSelfClosingElement(4930 generator.createIdentifier("div"),4931 undefined,4932 [4933 generator.createJsxAttribute(4934 generator.createIdentifier("v"),4935 generator.createIdentifier("height")4936 ),4937 ]4938 )4939 ),4940 ],4941 false4942 );4943 const expression = generator.createFunctionDeclaration(4944 [],4945 [],4946 "",4947 generator.createIdentifier("View"),4948 [],4949 [4950 generator.createParameter(4951 [],4952 [],4953 undefined,4954 generator.createObjectBindingPattern([4955 generator.createBindingElement(4956 undefined,4957 undefined,4958 generator.createIdentifier("height"),4959 undefined4960 ),4961 ]),4962 undefined,4963 undefined,4964 undefined4965 ),4966 ],4967 undefined,4968 block4969 );4970 const member = generator.createGetAccessor(4971 [],4972 [],4973 generator.createIdentifier("height"),4974 [],4975 undefined,4976 undefined4977 );4978 member.prefix = "__";4979 assert.strictEqual(expression.toString(), "");4980 assert.strictEqual(4981 expression.getTemplate({4982 members: [member],4983 newComponentContext: "",4984 }),4985 `<div [v]="__height"></div>`4986 );4987 });4988 mocha.it("Can decomposite component - props", function () {4989 const block = generator.createBlock(4990 [4991 generator.createReturn(4992 generator.createJsxSelfClosingElement(4993 generator.createIdentifier("div"),4994 undefined,4995 [4996 generator.createJsxAttribute(4997 generator.createIdentifier("v"),4998 generator.createPropertyAccess(4999 generator.createIdentifier("props"),5000 generator.createIdentifier("height")5001 )5002 ),5003 ]5004 )5005 ),5006 ],5007 false5008 );5009 const expression = generator.createFunctionDeclaration(5010 [],5011 [],5012 "",5013 generator.createIdentifier("View"),5014 [],5015 [5016 generator.createParameter(5017 [],5018 [],5019 undefined,5020 generator.createObjectBindingPattern([5021 generator.createBindingElement(5022 undefined,5023 undefined,5024 generator.createIdentifier("props"),5025 undefined5026 ),5027 ]),5028 undefined,5029 undefined,5030 undefined5031 ),5032 ],5033 undefined,5034 block5035 );5036 const member = generator.createProperty(5037 [createDecorator(Decorators.OneWay)],5038 [],5039 generator.createIdentifier("height")5040 );5041 assert.strictEqual(expression.toString(), "");5042 assert.strictEqual(5043 expression.getTemplate({5044 members: [member],5045 }),5046 `<div [v]="height"></div>`5047 );5048 });5049 mocha.it("Can use jsx variables in view function", function () {5050 const block = generator.createBlock(5051 [5052 generator.createVariableStatement(5053 [],5054 generator.createVariableDeclarationList(5055 [5056 generator.createVariableDeclaration(5057 generator.createIdentifier("v"),5058 undefined,5059 generator.createJsxSelfClosingElement(5060 generator.createIdentifier("span")5061 )5062 ),5063 ],5064 generator.SyntaxKind.ConstKeyword5065 )5066 ),5067 generator.createReturn(5068 generator.createJsxElement(5069 generator.createJsxOpeningElement(5070 generator.createIdentifier("div"),5071 [],5072 []5073 ),5074 [5075 generator.createJsxExpression(5076 undefined,5077 generator.createIdentifier("v")5078 ),5079 ],5080 generator.createJsxClosingElement(5081 generator.createIdentifier("div")5082 )5083 )5084 ),5085 ],5086 false5087 );5088 const expression = generator.createFunctionDeclaration(5089 [],5090 [],5091 "",5092 generator.createIdentifier("View"),5093 [],5094 [],5095 undefined,5096 block5097 );5098 assert.strictEqual(expression.toString(), "");5099 assert.strictEqual(5100 expression.getTemplate({5101 members: [],5102 }),5103 `<div ><ng-container *ngTemplateOutlet="v"></ng-container></div>`5104 );5105 });5106 mocha.it("Can use jsx variable twice", function () {5107 const block = generator.createBlock(5108 [5109 generator.createVariableStatement(5110 [],5111 generator.createVariableDeclarationList(5112 [5113 generator.createVariableDeclaration(5114 generator.createIdentifier("v"),5115 undefined,5116 generator.createJsxSelfClosingElement(5117 generator.createIdentifier("span")5118 )5119 ),5120 ],5121 generator.SyntaxKind.ConstKeyword5122 )5123 ),5124 generator.createReturn(5125 generator.createJsxElement(5126 generator.createJsxOpeningElement(5127 generator.createIdentifier("div"),5128 [],5129 []5130 ),5131 [5132 generator.createJsxExpression(5133 undefined,5134 generator.createBinary(5135 generator.createIdentifier("c1"),5136 generator.SyntaxKind.AmpersandAmpersandToken,5137 generator.createIdentifier("v")5138 )5139 ),5140 generator.createJsxExpression(5141 undefined,5142 generator.createBinary(5143 generator.createIdentifier("c2"),5144 generator.SyntaxKind.AmpersandAmpersandToken,5145 generator.createIdentifier("v")5146 )5147 ),5148 ],5149 generator.createJsxClosingElement(5150 generator.createIdentifier("div")5151 )5152 )5153 ),5154 ],5155 false5156 );5157 const expression = generator.createFunctionDeclaration(5158 [],5159 [],5160 "",5161 generator.createIdentifier("View"),5162 [],5163 [],5164 undefined,5165 block5166 );5167 assert.strictEqual(expression.toString(), "");5168 assert.strictEqual(5169 removeSpaces(5170 expression.getTemplate({5171 members: [],5172 }) as string5173 ),5174 removeSpaces(`<div >5175 <span *ngIf="c1"></span>5176 <span *ngIf="c2"></span>5177 </div>`)5178 );5179 });5180 mocha.it("Can use jsx variable with condition", function () {5181 const block = generator.createBlock(5182 [5183 generator.createVariableStatement(5184 [],5185 generator.createVariableDeclarationList(5186 [5187 generator.createVariableDeclaration(5188 generator.createIdentifier("v"),5189 undefined,5190 generator.createBinary(5191 generator.createIdentifier("c1"),5192 generator.SyntaxKind.AmpersandAmpersandToken,5193 generator.createJsxSelfClosingElement(5194 generator.createIdentifier("span")5195 )5196 )5197 ),5198 ],5199 generator.SyntaxKind.ConstKeyword5200 )5201 ),5202 generator.createReturn(5203 generator.createJsxElement(5204 generator.createJsxOpeningElement(5205 generator.createIdentifier("div"),5206 [],5207 []5208 ),5209 [5210 generator.createJsxExpression(5211 undefined,5212 generator.createBinary(5213 generator.createIdentifier("c2"),5214 generator.SyntaxKind.AmpersandAmpersandToken,5215 generator.createIdentifier("v")5216 )5217 ),5218 ],5219 generator.createJsxClosingElement(5220 generator.createIdentifier("div")5221 )5222 )5223 ),5224 ],5225 false5226 );5227 const expression = generator.createFunctionDeclaration(5228 [],5229 [],5230 "",5231 generator.createIdentifier("View"),5232 [],5233 [],5234 undefined,5235 block5236 );5237 assert.strictEqual(expression.toString(), "");5238 assert.strictEqual(5239 removeSpaces(5240 expression.getTemplate({5241 members: [],5242 }) as string5243 ),5244 removeSpaces(`<div >5245 <span *ngIf="(c1)&&c2"></span>5246 </div>`)5247 );5248 });5249 mocha.it("Can store map in variable", function () {5250 const block = generator.createBlock(5251 [5252 generator.createVariableStatement(5253 [],5254 generator.createVariableDeclarationList(5255 [5256 generator.createVariableDeclaration(5257 generator.createIdentifier("v"),5258 undefined,5259 generator.createCall(5260 generator.createPropertyAccess(5261 generator.createPropertyAccess(5262 generator.createIdentifier("viewModel"),5263 generator.createIdentifier("items")5264 ),5265 generator.createIdentifier("map")5266 ),5267 undefined,5268 [5269 generator.createArrowFunction(5270 undefined,5271 undefined,5272 [5273 generator.createParameter(5274 undefined,5275 undefined,5276 undefined,5277 generator.createIdentifier("items"),5278 undefined,5279 undefined,5280 undefined5281 ),5282 ],5283 undefined,5284 generator.createToken(5285 generator.SyntaxKind.EqualsGreaterThanToken5286 ),5287 generator.createJsxElement(5288 generator.createJsxOpeningElement(5289 generator.createIdentifier("div"),5290 undefined,5291 generator.createJsxAttributes([])5292 ),5293 [],5294 generator.createJsxClosingElement(5295 generator.createIdentifier("div")5296 )5297 )5298 ),5299 ]5300 )5301 ),5302 ],5303 generator.SyntaxKind.ConstKeyword5304 )5305 ),5306 generator.createReturn(5307 generator.createJsxElement(5308 generator.createJsxOpeningElement(5309 generator.createIdentifier("div"),5310 [],5311 []5312 ),5313 [5314 generator.createJsxExpression(5315 undefined,5316 generator.createIdentifier("v")5317 ),5318 ],5319 generator.createJsxClosingElement(5320 generator.createIdentifier("div")5321 )5322 )5323 ),5324 ],5325 false5326 );5327 const expression = generator.createFunctionDeclaration(5328 [],5329 [],5330 "",5331 generator.createIdentifier("View"),5332 [],5333 [],5334 undefined,5335 block5336 );5337 assert.strictEqual(expression.toString(), "");5338 assert.strictEqual(5339 removeSpaces(5340 expression.getTemplate({5341 members: [],5342 }) as string5343 ),5344 removeSpaces(`<div>5345 <ng-container *ngFor="let items of viewModel.items">5346 <div ></div>5347 </ng-container>5348 </div>`)5349 );5350 });5351 mocha.it(5352 "Convert to template function with ternary operator",5353 function () {5354 this.block.statements = [5355 generator.createReturn(5356 generator.createConditional(5357 generator.createTrue(),5358 generator.createJsxSelfClosingElement(5359 generator.createIdentifier("div")5360 ),5361 generator.createJsxSelfClosingElement(5362 generator.createIdentifier("span")5363 )5364 )5365 ),5366 ];5367 const expression = generator.createFunctionDeclaration(5368 [],5369 [],5370 "",5371 generator.createIdentifier("View"),5372 [],5373 [],5374 undefined,5375 this.block5376 );5377 assert.strictEqual(expression.toString(), "");5378 assert.strictEqual(5379 removeSpaces(expression.getTemplate()),5380 removeSpaces(`5381 <div *ngIf="true"></div>5382 <span *ngIf="!(true)"></span>5383 `)5384 );5385 }5386 );5387 });5388 });5389 mocha.describe("Decorators", function () {5390 mocha.it("OneWay -> Input", function () {5391 const decorator = createDecorator(Decorators.OneWay);5392 assert.strictEqual(decorator.name, Decorators.OneWay);5393 assert.strictEqual(decorator.toString(), "@Input()");5394 });5395 mocha.it("TwoWay -> Output", function () {5396 const decorator = createDecorator(Decorators.TwoWay);5397 assert.strictEqual(decorator.toString(), "@Input()");5398 });5399 mocha.it("Event -> Output", function () {5400 const decorator = createDecorator(Decorators.Event);5401 assert.strictEqual(decorator.toString(), "@Output()");5402 });5403 mocha.it("Template -> Input", function () {5404 const decorator = createDecorator("Template");5405 assert.strictEqual(decorator.toString(), "@Input()");5406 });5407 mocha.it("Effect -> ''", function () {5408 const decorator = createDecorator("Effect");5409 assert.strictEqual(decorator.toString(), "");5410 });5411 mocha.it("Ref -> ''", function () {5412 const decorator = createDecorator(Decorators.Ref);5413 assert.strictEqual(decorator.toString(), "");5414 });5415 mocha.it("InternalState -> ''", function () {5416 const decorator = createDecorator("InternalState");5417 assert.strictEqual(decorator.toString(), "");5418 });5419 mocha.describe("Component", function () {5420 this.beforeEach(function () {5421 generator.setContext({});5422 });5423 this.afterEach(function () {5424 generator.setContext(null);5425 });5426 mocha.it("Replace viewFunction with template", function () {5427 generator.createFunctionDeclaration(5428 [],5429 [],5430 "",5431 generator.createIdentifier("viewFunction"),5432 [],5433 [],5434 undefined,5435 generator.createBlock(5436 [5437 generator.createReturn(5438 generator.createJsxSelfClosingElement(5439 generator.createIdentifier("div")5440 )5441 ),5442 ],5443 false5444 )5445 );5446 const decorator = generator.createDecorator(5447 generator.createCall(5448 generator.createIdentifier("Component"),5449 [],5450 [5451 generator.createObjectLiteral(5452 [5453 generator.createPropertyAssignment(5454 generator.createIdentifier("view"),5455 generator.createIdentifier("viewFunction")5456 ),5457 ],5458 false5459 ),5460 ]5461 )5462 );5463 assert.strictEqual(5464 decorator.toString(),5465 `@Component({template:\`<div ></div>\`})`5466 );5467 });5468 mocha.it("Add templates for variable with element", function () {5469 generator.createFunctionDeclaration(5470 [],5471 [],5472 "",5473 generator.createIdentifier("viewFunction"),5474 [],5475 [],5476 undefined,5477 generator.createBlock(5478 [5479 generator.createReturn(5480 generator.createJsxSelfClosingElement(5481 generator.createIdentifier("div")5482 )5483 ),5484 ],5485 false5486 )5487 );5488 const decorator = generator.createDecorator(5489 generator.createCall(5490 generator.createIdentifier("Component"),5491 [],5492 [5493 generator.createObjectLiteral(5494 [5495 generator.createPropertyAssignment(5496 generator.createIdentifier("view"),5497 generator.createIdentifier("viewFunction")5498 ),5499 ],5500 false5501 ),5502 ]5503 )5504 );5505 assert.strictEqual(5506 removeSpaces(5507 decorator.toString({5508 members: [],5509 variables: {5510 v1: generator.createJsxSelfClosingElement(5511 generator.createIdentifier("span")5512 ),5513 v2: generator.createIdentifier("id"),5514 },5515 })5516 ),5517 removeSpaces(5518 "@Component({template:`<div ></div>\n" +5519 "<ng-template #v1>" +5520 "<span ></span>" +5521 "</ng-template>" +5522 "`})"5523 )5524 );5525 });5526 mocha.it("Add templates for variable with element in paren", function () {5527 generator.createFunctionDeclaration(5528 [],5529 [],5530 "",5531 generator.createIdentifier("viewFunction"),5532 [],5533 [],5534 undefined,5535 generator.createBlock(5536 [5537 generator.createReturn(5538 generator.createJsxSelfClosingElement(5539 generator.createIdentifier("div")5540 )5541 ),5542 ],5543 false5544 )5545 );5546 const decorator = generator.createDecorator(5547 generator.createCall(5548 generator.createIdentifier("Component"),5549 [],5550 [5551 generator.createObjectLiteral(5552 [5553 generator.createPropertyAssignment(5554 generator.createIdentifier("view"),5555 generator.createIdentifier("viewFunction")5556 ),5557 ],5558 false5559 ),5560 ]5561 )5562 );5563 assert.strictEqual(5564 removeSpaces(5565 decorator.toString({5566 members: [],5567 variables: {5568 v1: generator.createParen(5569 generator.createJsxSelfClosingElement(5570 generator.createIdentifier("span")5571 )5572 ),5573 },5574 })5575 ),5576 removeSpaces(5577 "@Component({template:`<div ></div>\n" +5578 "<ng-template #v1>" +5579 "<span ></span>" +5580 "</ng-template>" +5581 "`})"5582 )5583 );5584 });5585 mocha.it("should remove all declaration parameters", function () {5586 const parameters: Required<5587 { [key in keyof ComponentParameters]: boolean }5588 > = {5589 components: true,5590 name: true,5591 isSVG: true,5592 view: true,5593 defaultOptionRules: true,5594 jQuery: true,5595 };5596 const decorator = generator.createDecorator(5597 generator.createCall(5598 generator.createIdentifier("Component"),5599 [],5600 [5601 generator.createObjectLiteral(5602 Object.keys(parameters).map((name) =>5603 generator.createPropertyAssignment(5604 generator.createIdentifier(name),5605 generator.createIdentifier(name)5606 )5607 ),5608 false5609 ),5610 ]5611 )5612 );5613 assert.strictEqual(decorator.toString(), `@Component({})`);5614 });5615 mocha.describe("CompileSpreadAttributes", function () {5616 const createView = (spreadExpression: Expression) =>5617 generator.createVariableDeclaration(5618 generator.createIdentifier("view"),5619 undefined,5620 generator.createArrowFunction(5621 [],5622 [],5623 [5624 generator.createParameter(5625 [],5626 [],5627 undefined,5628 generator.createIdentifier("viewModel"),5629 undefined,5630 generator.createTypeReferenceNode(5631 generator.createIdentifier("BaseWidget")5632 )5633 ),5634 ],5635 undefined,5636 generator.SyntaxKind.EqualsGreaterThanToken,5637 generator.createJsxSelfClosingElement(5638 generator.createIdentifier("div"),5639 undefined,5640 [5641 generator.createJsxAttribute(5642 generator.createIdentifier("ref"),5643 generator.createIdentifier("ref")5644 ),5645 generator.createJsxSpreadAttribute(spreadExpression),5646 ]5647 )5648 )5649 );5650 mocha.it("...prop", function () {5651 const prop = generator.createProperty(5652 [createDecorator(Decorators.OneWay)],5653 [],5654 generator.createIdentifier("attr")5655 );5656 createView(5657 generator.createPropertyAccess(5658 generator.createPropertyAccess(5659 generator.createIdentifier("viewModel"),5660 generator.createIdentifier("props")5661 ),5662 generator.createIdentifier("attr")5663 )5664 );5665 const component = createComponent([prop], {5666 view: generator.createIdentifier("view"),5667 }) as AngularComponent;5668 const ngOnChanges: string[] = [];5669 component.compileSpreadAttributes(ngOnChanges, [], [], []);5670 assert.strictEqual(5671 getResult(ngOnChanges.join(";\n")),5672 getResult(`5673 if(["attr"].some(d=>changes[d] && !changes[d].firstChange)){5674 this.scheduledApplyAttributes = true;5675 }`)5676 );5677 });5678 mocha.it("...getter", function () {5679 const prop = generator.createProperty(5680 [createDecorator(Decorators.OneWay)],5681 [],5682 generator.createIdentifier("prop")5683 );5684 const getter = generator.createGetAccessor(5685 [],5686 [],5687 generator.createIdentifier("attr"),5688 [],5689 undefined,5690 generator.createBlock(5691 [5692 generator.createReturn(5693 generator.createPropertyAccess(5694 generator.createPropertyAccess(5695 generator.createThis(),5696 generator.createIdentifier("props")5697 ),5698 generator.createIdentifier("prop")5699 )5700 ),5701 ],5702 false5703 )5704 );5705 createView(5706 generator.createPropertyAccess(5707 generator.createIdentifier("viewModel"),5708 generator.createIdentifier("attr")5709 )5710 );5711 const component = createComponent([prop, getter], {5712 view: generator.createIdentifier("view"),5713 }) as AngularComponent;5714 const ngOnChanges: string[] = [];5715 component.compileSpreadAttributes(ngOnChanges, [], [], []);5716 assert.strictEqual(5717 getResult(ngOnChanges.join(";\n")),5718 getResult(`5719 if(["prop"].some(d=>changes[d] && !changes[d].firstChange)){5720 this.scheduledApplyAttributes = true;5721 }`)5722 );5723 });5724 mocha.it("...method", function () {5725 const prop = generator.createProperty(5726 [createDecorator(Decorators.OneWay)],5727 [],5728 generator.createIdentifier("prop")5729 );5730 const method = generator.createMethod(5731 [],5732 [],5733 undefined,5734 generator.createIdentifier("attr"),5735 undefined,5736 undefined,5737 [],5738 undefined,5739 generator.createBlock(5740 [5741 generator.createVariableDeclaration(5742 generator.createObjectBindingPattern([5743 generator.createBindingElement(5744 undefined,5745 undefined,5746 generator.createIdentifier("prop")5747 ),5748 ]),5749 undefined,5750 generator.createThis()5751 ),5752 ],5753 false5754 )5755 );5756 createView(5757 generator.createCall(5758 generator.createPropertyAccess(5759 generator.createIdentifier("viewModel"),5760 generator.createIdentifier("attr")5761 ),5762 undefined,5763 []5764 )5765 );5766 const component = createComponent([prop, method], {5767 view: generator.createIdentifier("view"),5768 }) as AngularComponent;5769 const ngOnChanges: string[] = [];5770 component.compileSpreadAttributes(ngOnChanges, [], [], []);5771 assert.strictEqual(5772 getResult(ngOnChanges.join(";\n")),5773 getResult(`5774 if(["prop"].some(d=>changes[d] && !changes[d].firstChange)){5775 this.scheduledApplyAttributes = true;5776 }`)5777 );5778 });5779 mocha.it("...internalState", function () {5780 const state = generator.createProperty(5781 [createDecorator(Decorators.InternalState)],5782 [],5783 generator.createIdentifier("attr")5784 );5785 createView(5786 generator.createPropertyAccess(5787 generator.createIdentifier("viewModel"),5788 generator.createIdentifier("attr")5789 )5790 );5791 const component = createComponent([state], {5792 view: generator.createIdentifier("view"),5793 }) as AngularComponent;5794 const ngOnChanges: string[] = [];5795 component.compileSpreadAttributes(ngOnChanges, [], [], []);5796 const internalStateSetter = component.members.find(5797 (m) => m.name.toString() === `_${state.name}`5798 ) as SetAccessor;5799 assert.strictEqual(ngOnChanges.join(";\n"), "");5800 assert.strictEqual(5801 getResult(internalStateSetter.body.toString()),5802 getResult(`{5803 this.attr=attr;5804 this._detectChanges();5805 this.scheduledApplyAttributes = this;5806 }`)5807 );5808 });5809 });5810 });5811 });5812 mocha.describe("ComponentBindings", function () {5813 this.beforeEach(function () {5814 generator.setContext({});5815 });5816 this.afterEach(function () {5817 generator.setContext(null);5818 });5819 mocha.it("Generate componentBindings as a class", function () {5820 const bindings = generator.createClassDeclaration(5821 [createDecorator("ComponentBindings")],5822 ["export", "default"],5823 generator.createIdentifier("ComponentInput"),5824 [],5825 [],5826 [5827 generator.createProperty(5828 [createDecorator(Decorators.OneWay)],5829 [],5830 generator.createIdentifier("p1"),5831 generator.SyntaxKind.QuestionToken,5832 generator.createKeywordTypeNode("number"),5833 generator.createNumericLiteral("10")5834 ),5835 generator.createProperty(5836 [createDecorator(Decorators.OneWay)],5837 [],5838 generator.createIdentifier("p2"),5839 generator.SyntaxKind.QuestionToken,5840 generator.createKeywordTypeNode("number"),5841 generator.createNumericLiteral("11")5842 ),5843 ]5844 );5845 assert.strictEqual(5846 getResult(bindings.toString()),5847 getResult(`5848 import {Input} from "@angular/core"5849 export default class ComponentInput {5850 @Input() p1?:number = 10;5851 @Input() p2?:number = 11;5852 }`)5853 );5854 });5855 mocha.it("Do not include inherited props", function () {5856 generator.createClassDeclaration(5857 [createDecorator("ComponentBindings")],5858 ["export", "default"],5859 generator.createIdentifier("Base"),5860 [],5861 [],5862 [5863 generator.createProperty(5864 [createDecorator(Decorators.OneWay)],5865 [],5866 generator.createIdentifier("p1"),5867 generator.SyntaxKind.QuestionToken,5868 generator.createKeywordTypeNode("number"),5869 generator.createNumericLiteral("10")5870 ),5871 ]5872 );5873 const heritageClause = generator.createHeritageClause(5874 generator.SyntaxKind.ExtendsKeyword,5875 [5876 generator.createExpressionWithTypeArguments(5877 undefined,5878 generator.createIdentifier("Base")5879 ),5880 ]5881 );5882 const child = generator.createClassDeclaration(5883 [createDecorator("ComponentBindings")],5884 ["export", "default"],5885 generator.createIdentifier("Child"),5886 [],5887 [heritageClause],5888 []5889 );5890 assert.strictEqual(5891 getResult(child.toString()),5892 getResult("export default class Child extends Base {}")5893 );5894 });5895 mocha.it("Ref Prop generates ViewChild", function () {5896 const property = generator.createProperty(5897 [createDecorator(Decorators.Ref)],5898 [],5899 generator.createIdentifier("host"),5900 generator.SyntaxKind.QuestionToken,5901 generator.createKeywordTypeNode("HTMLDivElement"),5902 generator.createArrowFunction(5903 [],5904 [],5905 [],5906 undefined,5907 generator.SyntaxKind.EqualsGreaterThanToken,5908 generator.createNull()5909 )5910 );5911 assert.strictEqual(5912 property.toString(),5913 `@ViewChild("host", {static: false}) host?:ElementRef<HTMLDivElement>`5914 );5915 });5916 mocha.it("Ref Prop getter type is not element", function () {5917 const property = generator.createProperty(5918 [createDecorator(Decorators.Ref)],5919 [],5920 generator.createIdentifier("host"),5921 generator.SyntaxKind.QuestionToken,5922 generator.createKeywordTypeNode("NotElement")5923 );5924 assert.strictEqual(5925 property.getter(generator.SyntaxKind.ThisKeyword),5926 "this.host"5927 );5928 });5929 mocha.it(5930 "Template property with exclamation token should ignore token",5931 function () {5932 const property = generator.createProperty(5933 [createDecorator(Decorators.Template)],5934 [],5935 generator.createIdentifier("template"),5936 generator.SyntaxKind.ExclamationToken,5937 generator.createKeywordTypeNode(generator.SyntaxKind.AnyKeyword)5938 );5939 assert.strictEqual(5940 property.toString(),5941 " @Input() template:TemplateRef<any> | null = null"5942 );5943 }5944 );5945 mocha.it("Event Prop generates Event EventEmitter", function () {5946 const property = generator.createProperty(5947 [createDecorator(Decorators.Event)],5948 [],5949 generator.createIdentifier("onClick"),5950 generator.SyntaxKind.QuestionToken,5951 undefined,5952 generator.createArrowFunction(5953 [],5954 [],5955 [],5956 undefined,5957 generator.SyntaxKind.EqualsGreaterThanToken,5958 generator.createNull()5959 )5960 );5961 assert.strictEqual(5962 getResult(property.toString()),5963 getResult(`5964 @Output() onClick:EventEmitter<any> = new EventEmitter();5965 `)5966 );5967 });5968 mocha.it("Event Prop with type FunctionNodeType", function () {5969 const property = generator.createProperty(5970 [createDecorator(Decorators.Event)],5971 [],5972 generator.createIdentifier("onClick"),5973 generator.SyntaxKind.QuestionToken,5974 generator.createFunctionTypeNode(5975 undefined,5976 [5977 generator.createParameter(5978 [],5979 [],5980 undefined,5981 generator.createIdentifier("a"),5982 generator.SyntaxKind.QuestionToken,5983 generator.createKeywordTypeNode("string"),5984 undefined5985 ),5986 generator.createParameter(5987 [],5988 [],5989 undefined,5990 generator.createIdentifier("b"),5991 undefined,5992 generator.createKeywordTypeNode("number"),5993 undefined5994 ),5995 ],5996 generator.createKeywordTypeNode("any")5997 ),5998 generator.createArrowFunction(5999 [],6000 [],6001 [],6002 undefined,6003 generator.SyntaxKind.EqualsGreaterThanToken,6004 generator.createNull()6005 )6006 );6007 assert.strictEqual(6008 getResult(property.toString()),6009 getResult(`6010 @Output() onClick:EventEmitter<string|undefined,number> = new EventEmitter();6011 `)6012 );6013 });6014 mocha.it(6015 "Event Prop with type FunctionNodeType without parameters",6016 function () {6017 const property = generator.createProperty(6018 [createDecorator(Decorators.Event)],6019 [],6020 generator.createIdentifier("onClick"),6021 generator.SyntaxKind.QuestionToken,6022 generator.createFunctionTypeNode(6023 undefined,6024 [],6025 generator.createKeywordTypeNode("any")6026 ),6027 generator.createArrowFunction(6028 [],6029 [],6030 [],6031 undefined,6032 generator.SyntaxKind.EqualsGreaterThanToken,6033 generator.createNull()6034 )6035 );6036 assert.strictEqual(6037 getResult(property.toString()),6038 getResult(`6039 @Output() onClick:EventEmitter<void> = new EventEmitter();6040 `)6041 );6042 }6043 );6044 mocha.it("Generate change for TwoWay prop with type", function () {6045 const bindings = generator.createClassDeclaration(6046 [createDecorator("ComponentBindings")],6047 ["export", "default"],6048 generator.createIdentifier("ComponentInput"),6049 [],6050 [],6051 [6052 generator.createProperty(6053 [createDecorator(Decorators.TwoWay)],6054 [],6055 generator.createIdentifier("p1"),6056 generator.SyntaxKind.QuestionToken,6057 generator.createKeywordTypeNode("number"),6058 generator.createNumericLiteral("10")6059 ),6060 ]6061 );6062 assert.strictEqual(bindings.members.length, 2);6063 assert.strictEqual(6064 getResult(bindings.members[1].toString()),6065 getResult(`6066 @Output() p1Change:EventEmitter<number|undefined> = new EventEmitter();6067 `)6068 );6069 });6070 mocha.it("TwoWay without type", function () {6071 const property = generator.createProperty(6072 [createDecorator(Decorators.TwoWay)],6073 [],6074 generator.createIdentifier("pressed"),6075 generator.SyntaxKind.QuestionToken,6076 undefined,6077 generator.createFalse()6078 );6079 assert.strictEqual(6080 getResult(property.toString()),6081 getResult(`@Input() pressed?:boolean = false`)6082 );6083 });6084 mocha.it("TwoWay without type and initializer", function () {6085 const property = generator.createProperty(6086 [createDecorator(Decorators.TwoWay)],6087 [],6088 generator.createIdentifier("pressed"),6089 generator.SyntaxKind.QuestionToken6090 );6091 assert.strictEqual(6092 getResult(property.toString()),6093 getResult(`@Input() pressed?:any`)6094 );6095 });6096 mocha.it("@Slot prop should generate getter", function () {6097 const property = generator.createProperty(6098 [createDecorator("Slot")],6099 [],6100 generator.createIdentifier("name"),6101 generator.SyntaxKind.QuestionToken,6102 undefined,6103 generator.createFalse()6104 );6105 assert.strictEqual(6106 getResult(property.toString()),6107 getResult(`6108 __slotName?: ElementRef<HTMLDivElement>;6109 get name(){6110 const childNodes = this.__slotName?.nativeElement?.childNodes;6111 return childNodes && childNodes.length > 26112 }6113 `)6114 );6115 });6116 mocha.it("@Template prop without type", function () {6117 const property = generator.createProperty(6118 [createDecorator("Template")],6119 [],6120 generator.createIdentifier("name"),6121 generator.SyntaxKind.QuestionToken,6122 undefined,6123 generator.createFalse()6124 );6125 assert.strictEqual(6126 property.toString(),6127 " @Input() name?:TemplateRef<any> | null = null"6128 );6129 });6130 mocha.it("get prop with same name in get accessor", function () {6131 const property = generator.createGetAccessor(6132 [],6133 [],6134 generator.createIdentifier("name"),6135 [],6136 undefined,6137 generator.createBlock(6138 [6139 generator.createPropertyAccess(6140 generator.createPropertyAccess(6141 generator.createThis(),6142 generator.createIdentifier("props")6143 ),6144 generator.createIdentifier("name")6145 ),6146 ],6147 false6148 )6149 );6150 property.prefix = "_";6151 const prop = generator6152 .createProperty(6153 [createDecorator(Decorators.OneWay)],6154 [],6155 generator.createIdentifier("name")6156 )6157 .inherit();6158 assert.strictEqual(6159 getResult(6160 property.toString({6161 members: [property, prop],6162 componentContext: generator.SyntaxKind.ThisKeyword,6163 newComponentContext: generator.SyntaxKind.ThisKeyword,6164 })6165 ),6166 getResult("get _name(): any{this.name}")6167 );6168 });6169 });6170 mocha.describe("Angular Component", function () {6171 mocha.it("Calculate Selector", function () {6172 const decorator = createComponentDecorator({});6173 const component = generator.createComponent(6174 decorator,6175 [],6176 generator.createIdentifier("BaseWidget"),6177 [],6178 [],6179 []6180 );6181 assert.strictEqual(component.selector, "dx-base-widget");6182 assert.strictEqual(6183 decorator.toString(),6184 `@Component({selector:"dx-base-widget",changeDetection:ChangeDetectionStrategy.OnPush})`6185 );6186 });6187 mocha.describe("Imports", function () {6188 mocha.it("Empty component", function () {6189 const component = createComponent() as AngularComponent;6190 assert.strictEqual(6191 getResult(component.compileImports()),6192 getResult(6193 `import { Component, NgModule } from "@angular/core"; import {CommonModule} from "@angular/common"`6194 )6195 );6196 });6197 mocha.it("Has OneWay property - Input", function () {6198 const component = createComponent([6199 generator.createProperty(6200 [createDecorator(Decorators.OneWay)],6201 [],6202 generator.createIdentifier("p")6203 ),6204 ]) as AngularComponent;6205 assert.strictEqual(6206 getResult(component.compileImports()),6207 getResult(6208 `import { Component, NgModule, Input } from "@angular/core"; import {CommonModule} from "@angular/common"`6209 )6210 );6211 });6212 mocha.it("Has Template property - Input, TemplateRef", function () {6213 const component = createComponent([6214 generator.createProperty(6215 [createDecorator("Template")],6216 [],6217 generator.createIdentifier("p")6218 ),6219 ]) as AngularComponent;6220 assert.strictEqual(6221 getResult(component.compileImports()),6222 getResult(6223 `import { Component, NgModule, Input, TemplateRef } from "@angular/core"; import {CommonModule} from "@angular/common"`6224 )6225 );6226 });6227 mocha.it(6228 "Has TwoWay property - Input, Output, EventEmitter",6229 function () {6230 const component = createComponent([6231 generator.createProperty(6232 [createDecorator(Decorators.TwoWay)],6233 [],6234 generator.createIdentifier("p")6235 ),6236 ]) as AngularComponent;6237 assert.strictEqual(6238 getResult(component.compileImports()),6239 getResult(6240 `import { Component, NgModule, Input, Output, EventEmitter } from "@angular/core"; import {CommonModule} from "@angular/common"`6241 )6242 );6243 }6244 );6245 mocha.it("Import should not have duplicates", function () {6246 const component = createComponent([6247 generator.createProperty(6248 [createDecorator(Decorators.OneWay)],6249 [],6250 generator.createIdentifier("p")6251 ),6252 generator.createProperty(6253 [createDecorator(Decorators.TwoWay)],6254 [],6255 generator.createIdentifier("p")6256 ),6257 ]) as AngularComponent;6258 assert.strictEqual(6259 getResult(component.compileImports()),6260 getResult(6261 `import { Component, NgModule, Input, Output, EventEmitter } from "@angular/core"; import {CommonModule} from "@angular/common"`6262 )6263 );6264 });6265 mocha.it("Has Event property - Output, EventEmitter", function () {6266 const component = createComponent([6267 generator.createProperty(6268 [createDecorator(Decorators.Event)],6269 [],6270 generator.createIdentifier("p")6271 ),6272 ]) as AngularComponent;6273 assert.strictEqual(6274 getResult(component.compileImports()),6275 getResult(6276 `import { Component, NgModule, Output, EventEmitter } from "@angular/core"; import {CommonModule} from "@angular/common"`6277 )6278 );6279 });6280 mocha.it("Has Ref property - ViewChild, ElementRef", function () {6281 const component = createComponent([6282 generator.createProperty(6283 [createDecorator(Decorators.Ref)],6284 [],6285 generator.createIdentifier("p")6286 ),6287 ]) as AngularComponent;6288 assert.strictEqual(6289 getResult(component.compileImports()),6290 getResult(6291 `import { Component, NgModule, ViewChild, ElementRef } from "@angular/core"; import {CommonModule} from "@angular/common"`6292 )6293 );6294 });6295 });6296 mocha.it("generate component skeleton", function () {6297 const component = generator.createComponent(6298 createComponentDecorator({}),6299 [6300 generator.SyntaxKind.ExportKeyword,6301 generator.SyntaxKind.DefaultKeyword,6302 ],6303 generator.createIdentifier("BaseWidget"),6304 [],6305 [],6306 []6307 );6308 assert.strictEqual(6309 getResult(component.toString()),6310 getResult(`6311 import {Component,NgModule,ChangeDetectionStrategy,ChangeDetectorRef,ViewRef} from "@angular/core";6312 import {CommonModule} from "@angular/common";6313 ${component.decorator}6314 export default class BaseWidget {6315 get __restAttributes(): any{6316 return {}6317 }6318 _detectChanges(): void {6319 setTimeout(() => {6320 if (this.changeDetection && !(this.changeDetection as ViewRef).destroyed)6321 this.changeDetection.detectChanges();6322 });6323 }6324 constructor(private changeDetection: ChangeDetectorRef) {}6325 }6326 @NgModule({6327 declarations: [BaseWidget],6328 imports: [6329 CommonModule6330 ],6331 exports: [BaseWidget]6332 })6333 export class DxBaseWidgetModule {}6334 export { BaseWidget as DxBaseWidgetComponent }6335 `)6336 );6337 });6338 mocha.it(6339 "generate component skeleton with extends of Component Bindings",6340 function () {6341 generator.createClassDeclaration(6342 [6343 generator.createDecorator(6344 generator.createCall(6345 generator.createIdentifier("ComponentBindings"),6346 [],6347 []6348 )6349 ),6350 ],6351 [],6352 generator.createIdentifier("Input"),6353 [],6354 [],6355 [6356 generator.createProperty(6357 [createDecorator(Decorators.OneWay)],6358 [],6359 generator.createIdentifier("p"),6360 "",6361 undefined,6362 generator.createNumericLiteral("10")6363 ),6364 ]6365 );6366 const heritageClause = generator.createHeritageClause(6367 generator.SyntaxKind.ExtendsKeyword,6368 [6369 generator.createExpressionWithTypeArguments(6370 [6371 generator.createTypeReferenceNode(6372 generator.createIdentifier("Input"),6373 undefined6374 ),6375 ],6376 generator.createIdentifier("JSXComponent")6377 ),6378 ]6379 );6380 const component = generator.createComponent(6381 createComponentDecorator({}),6382 [6383 generator.SyntaxKind.ExportKeyword,6384 generator.SyntaxKind.DefaultKeyword,6385 ],6386 generator.createIdentifier("BaseWidget"),6387 [],6388 [heritageClause],6389 []6390 );6391 assert.strictEqual(6392 getResult(component.toString()),6393 getResult(`6394 import {Component,NgModule,ChangeDetectionStrategy,ChangeDetectorRef,ViewRef} from "@angular/core";6395 import {CommonModule} from "@angular/common";6396 6397 ${component.decorator}6398 export default class BaseWidget extends Input {6399 get __restAttributes(): any{6400 return {}6401 }6402 _detectChanges(): void {6403 setTimeout(() => {6404 if (this.changeDetection && !(this.changeDetection as ViewRef).destroyed)6405 this.changeDetection.detectChanges();6406 });6407 }6408 constructor(private changeDetection: ChangeDetectorRef) {6409 super();6410 }6411 }6412 @NgModule({6413 declarations: [BaseWidget],6414 imports: [6415 CommonModule6416 ],6417 exports: [BaseWidget]6418 })6419 export class DxBaseWidgetModule {}6420 export { BaseWidget as DxBaseWidgetComponent }6421 `)6422 );6423 }6424 );6425 mocha.describe("Add setAccessor for InternalState", function () {6426 mocha.it("InternalState without token and type", function () {6427 const component = createComponent([6428 generator.createProperty(6429 [createDecorator(Decorators.InternalState)],6430 [],6431 generator.createIdentifier("p")6432 ),6433 ]);6434 const setter = component.members.filter(6435 (m) => m instanceof SetAccessor6436 );6437 assert.strictEqual(setter.length, 1);6438 assert.strictEqual(6439 getResult(setter[0].toString()),6440 getResult(`set _p(p:any){6441 this.p=p;6442 this._detectChanges();6443 }`)6444 );6445 });6446 mocha.it("InternalState with question token and type", function () {6447 const component = createComponent([6448 generator.createProperty(6449 [createDecorator(Decorators.InternalState)],6450 [],6451 generator.createIdentifier("p"),6452 generator.SyntaxKind.QuestionToken,6453 generator.createKeywordTypeNode("string")6454 ),6455 ]);6456 const setter = component.members.filter(6457 (m) => m instanceof SetAccessor6458 );6459 assert.strictEqual(setter.length, 1);6460 assert.strictEqual(6461 getResult(setter[0].toString()),6462 getResult(`set _p(p:string){6463 this.p=p;6464 this._detectChanges();6465 }`)6466 );6467 });6468 mocha.it("InternalState without question token and type", function () {6469 const component = createComponent([6470 generator.createProperty(6471 [createDecorator(Decorators.InternalState)],6472 [],6473 generator.createIdentifier("p"),6474 undefined,6475 generator.createKeywordTypeNode("string")6476 ),6477 ]);6478 const setter = component.members.filter(6479 (m) => m instanceof SetAccessor6480 );6481 assert.strictEqual(setter.length, 1);6482 assert.strictEqual(6483 getResult(setter[0].toString()),6484 getResult(`set _p(p:string){6485 this.p=p;6486 this._detectChanges();6487 }`)6488 );6489 });6490 mocha.it("InternalState with question token and any type", function () {6491 const component = createComponent([6492 generator.createProperty(6493 [createDecorator(Decorators.InternalState)],6494 [],6495 generator.createIdentifier("p"),6496 generator.SyntaxKind.QuestionToken,6497 generator.createKeywordTypeNode("any")6498 ),6499 ]);6500 const setter = component.members.filter(6501 (m) => m instanceof SetAccessor6502 );6503 assert.strictEqual(setter.length, 1);6504 assert.strictEqual(6505 getResult(setter[0].toString()),6506 getResult(`set _p(p:any){6507 this.p=p;6508 this._detectChanges();6509 }`)6510 );6511 });6512 mocha.it("InternalState with exclamation token", function () {6513 const component = createComponent([6514 generator.createProperty(6515 [createDecorator(Decorators.InternalState)],6516 [],6517 generator.createIdentifier("p"),6518 generator.SyntaxKind.QuestionToken,6519 generator.createKeywordTypeNode("any")6520 ),6521 ]);6522 const setter = component.members.filter(6523 (m) => m instanceof SetAccessor6524 );6525 assert.strictEqual(setter.length, 1);6526 assert.strictEqual(6527 getResult(setter[0].toString()),6528 getResult(`set _p(p:any){6529 this.p=p;6530 this._detectChanges();6531 }`)6532 );6533 });6534 });6535 mocha.describe("Default options", function () {6536 function setupGenerator(context: GeneratorContext) {6537 generator.setContext(context);6538 }6539 this.beforeEach(function () {6540 setupGenerator({6541 dirname: path.join(__dirname, "test-cases"),6542 defaultOptionsModule: `${__dirname}/default_options`,6543 });6544 });6545 this.afterEach(function () {6546 generator.options = {};6547 generator.setContext(null);6548 });6549 mocha.it("Add import convertRulesToOptions, Rule", function () {6550 const component = createComponent([]) as AngularComponent;6551 assert.ok(6552 component6553 .compileImports()6554 .indexOf(6555 `import {convertRulesToOptions, Rule} from "../default_options"`6556 ) > -16557 );6558 });6559 mocha.it(6560 "Compile defaultOptions expression if defaultOptionRules expression is set",6561 function () {6562 const component = createComponent([], {6563 defaultOptionRules: generator.createIdentifier("rules"),6564 }) as AngularComponent;6565 assert.strictEqual(6566 getResult(component.compileDefaultOptions([])),6567 getResult(`6568 type BaseWidgetOptionRule = Rule<Partial<BaseWidget>>;6569 const __defaultOptionRules:BaseWidgetOptionRule[] = rules;6570 export function defaultOptions(rule: BaseWidgetOptionRule) { 6571 __defaultOptionRules.push(rule);6572 6573 }`)6574 );6575 }6576 );6577 mocha.it(6578 "Compile defaultOptions expression if defaultOptionRules expression is not set",6579 function () {6580 const component = createComponent([], {}) as AngularComponent;6581 assert.strictEqual(6582 getResult(component.compileDefaultOptions([])),6583 getResult(`6584 type BaseWidgetOptionRule = Rule<Partial<BaseWidget>>;6585 const __defaultOptionRules:BaseWidgetOptionRule[] = [];6586 export function defaultOptions(rule: BaseWidgetOptionRule) { 6587 __defaultOptionRules.push(rule);6588 6589 }`)6590 );6591 }6592 );6593 });6594 mocha.describe("Members generation", function () {6595 mocha.it("Access props - this.prop", function () {6596 const property = generator.createProperty(6597 [createDecorator(Decorators.OneWay)],6598 [],6599 generator.createIdentifier("width"),6600 undefined,6601 undefined,6602 undefined6603 );6604 const expression = generator.createPropertyAccess(6605 generator.createThis(),6606 generator.createIdentifier("width")6607 );6608 assert.strictEqual(6609 expression.toString({6610 members: [property],6611 componentContext: generator.SyntaxKind.ThisKeyword,6612 newComponentContext: generator.SyntaxKind.ThisKeyword,6613 }),6614 "this.width"6615 );6616 });6617 mocha.it("Access TwoWay prop - this.prop", function () {6618 const property = generator.createProperty(6619 [createDecorator(Decorators.TwoWay)],6620 [],6621 generator.createIdentifier("width")6622 );6623 const expression = generator.createPropertyAccess(6624 generator.createThis(),6625 generator.createIdentifier("width")6626 );6627 assert.strictEqual(6628 expression.toString({6629 members: [property],6630 componentContext: generator.SyntaxKind.ThisKeyword,6631 newComponentContext: generator.SyntaxKind.ThisKeyword,6632 }),6633 "this.width"6634 );6635 });6636 mocha.it("Access props - this.props.prop", function () {6637 const property = generator.createProperty(6638 [createDecorator(Decorators.OneWay)],6639 [],6640 generator.createIdentifier("width"),6641 undefined,6642 undefined,6643 undefined6644 );6645 const expression = generator.createPropertyAccess(6646 generator.createPropertyAccess(6647 generator.createThis(),6648 generator.createIdentifier("props")6649 ),6650 generator.createIdentifier("width")6651 );6652 assert.strictEqual(6653 expression.toString({6654 members: [property],6655 componentContext: generator.SyntaxKind.ThisKeyword,6656 newComponentContext: generator.SyntaxKind.ThisKeyword,6657 }),6658 "this.width"6659 );6660 });6661 mocha.it(6662 "Access props - viewModel.props.prop -> newViewModel.prop",6663 function () {6664 const property = generator.createProperty(6665 [createDecorator(Decorators.OneWay)],6666 [],6667 generator.createIdentifier("width"),6668 undefined,6669 undefined,6670 undefined6671 );6672 const expression = generator.createPropertyAccess(6673 generator.createPropertyAccess(6674 generator.createIdentifier("viewModel"),6675 generator.createIdentifier("props")6676 ),6677 generator.createIdentifier("width")6678 );6679 assert.strictEqual(6680 expression.toString({6681 members: [property],6682 componentContext: "viewModel",6683 newComponentContext: "newViewModel",6684 }),6685 "newViewModel.width"6686 );6687 }6688 );6689 mocha.it("Access props - viewModel.props.prop", function () {6690 const property = generator.createProperty(6691 [createDecorator(Decorators.OneWay)],6692 [],6693 generator.createIdentifier("width")6694 );6695 const expression = generator.createPropertyAccess(6696 generator.createPropertyAccess(6697 generator.createIdentifier("viewModel"),6698 generator.createIdentifier("props")6699 ),6700 generator.createIdentifier("width")6701 );6702 assert.strictEqual(6703 expression.toString({6704 members: [property],6705 componentContext: "viewModel",6706 newComponentContext: "newViewModel",6707 }),6708 "newViewModel.width"6709 );6710 });6711 mocha.it("Access props - viewModel.props.prop - prop", function () {6712 const property = generator6713 .createProperty(6714 [createDecorator(Decorators.OneWay)],6715 [],6716 generator.createIdentifier("width")6717 )6718 .inherit();6719 const expression = generator.createPropertyAccess(6720 generator.createPropertyAccess(6721 generator.createIdentifier("viewModel"),6722 generator.createIdentifier("props")6723 ),6724 generator.createIdentifier("width")6725 );6726 assert.strictEqual(6727 expression.toString({6728 members: [property],6729 componentContext: "viewModel",6730 newComponentContext: "",6731 }),6732 "width"6733 );6734 });6735 mocha.it("Access props - this.props without members", function () {6736 const expression = generator.createPropertyAccess(6737 generator.createThis(),6738 generator.createIdentifier("props")6739 );6740 const stringValue = expression.toString({6741 members: [],6742 componentContext: generator.SyntaxKind.ThisKeyword,6743 newComponentContext: generator.SyntaxKind.ThisKeyword,6744 });6745 assert.strictEqual(stringValue, "{}");6746 });6747 mocha.it(6748 "Access props - this.props in bindingPattern statement",6749 function () {6750 const variableDeclaration = generator.createVariableDeclaration(6751 generator.createObjectBindingPattern([6752 generator.createBindingElement(6753 undefined,6754 undefined,6755 generator.createIdentifier("p")6756 ),6757 ]),6758 undefined,6759 generator.createPropertyAccess(6760 generator.createThis(),6761 generator.createIdentifier("props")6762 )6763 );6764 const stringValue = variableDeclaration.toString({6765 members: [6766 generator.createProperty(6767 [createDecorator(Decorators.OneWay)],6768 [],6769 generator.createIdentifier("p")6770 ),6771 ],6772 componentContext: generator.SyntaxKind.ThisKeyword,6773 newComponentContext: generator.SyntaxKind.ThisKeyword,6774 });6775 assert.strictEqual(stringValue, "{p}=this");6776 }6777 );6778 mocha.it("Access props - this.props with members", function () {6779 const expression = generator.createPropertyAccess(6780 generator.createThis(),6781 generator.createIdentifier("props")6782 );6783 const members = [6784 generator.createProperty(6785 [createDecorator(Decorators.OneWay)],6786 [],6787 generator.createIdentifier("p1")6788 ),6789 generator.createProperty(6790 [createDecorator(Decorators.TwoWay)],6791 [],6792 generator.createIdentifier("p2")6793 ),6794 generator.createProperty(6795 [createDecorator(Decorators.Event)],6796 [],6797 generator.createIdentifier("p3")6798 ),6799 generator.createProperty(6800 [createDecorator("Slot")],6801 [],6802 generator.createIdentifier("p4")6803 ),6804 generator.createProperty(6805 [createDecorator("Template")],6806 [],6807 generator.createIdentifier("p5")6808 ),6809 generator.createProperty(6810 [createDecorator("InternalState")],6811 [],6812 generator.createIdentifier("p6")6813 ),6814 generator.createMethod(6815 [],6816 [],6817 "",6818 generator.createIdentifier("p7"),6819 "",6820 undefined,6821 [],6822 undefined,6823 generator.createBlock([], false)6824 ),6825 generator.createGetAccessor(6826 [],6827 [],6828 generator.createIdentifier("p8"),6829 []6830 ),6831 ];6832 const stringValue = expression.toString({6833 members,6834 componentContext: generator.SyntaxKind.ThisKeyword,6835 newComponentContext: generator.SyntaxKind.ThisKeyword,6836 });6837 assert.strictEqual(6838 getResult(stringValue),6839 getResult(`{6840 p1:this.p1,6841 p2:this.p2,6842 p3:this._p3,6843 p4:this.p4,6844 p5:this.p56845 }`)6846 );6847 });6848 mocha.it("Access props - const {p} = this.props", function () {6849 const expression = generator.createPropertyAccess(6850 generator.createThis(),6851 generator.createIdentifier("props")6852 );6853 const members = [6854 generator.createProperty(6855 [createDecorator(Decorators.OneWay)],6856 [],6857 generator.createIdentifier("p1")6858 ),6859 generator.createProperty(6860 [createDecorator(Decorators.TwoWay)],6861 [],6862 generator.createIdentifier("p2")6863 ),6864 generator.createProperty(6865 [createDecorator(Decorators.Event)],6866 [],6867 generator.createIdentifier("p3")6868 ),6869 ];6870 const stringValue = generator6871 .createVariableDeclaration(6872 generator.createObjectBindingPattern([6873 generator.createBindingElement(6874 undefined,6875 undefined,6876 generator.createIdentifier("p1")6877 ),6878 generator.createBindingElement(6879 undefined,6880 generator.createIdentifier("p3"),6881 generator.createIdentifier("_p3")6882 ),6883 ]),6884 undefined,6885 expression6886 )6887 .toString({6888 componentContext: generator.SyntaxKind.ThisKeyword,6889 newComponentContext: generator.SyntaxKind.ThisKeyword,6890 members: members,6891 });6892 assert.strictEqual(6893 getResult(stringValue),6894 getResult(`{p1, p3:_p3}={p1:this.p1, p3:this._p3}`)6895 );6896 });6897 mocha.it("Access props - const {p} = (this.props as any)", function () {6898 const expression = generator.createParen(6899 generator.createAsExpression(6900 generator.createPropertyAccess(6901 generator.createThis(),6902 generator.createIdentifier("props")6903 ),6904 generator.createKeywordTypeNode("any")6905 )6906 );6907 const members = [6908 generator.createProperty(6909 [createDecorator(Decorators.OneWay)],6910 [],6911 generator.createIdentifier("p1")6912 ),6913 generator.createProperty(6914 [createDecorator(Decorators.TwoWay)],6915 [],6916 generator.createIdentifier("p2")6917 ),6918 generator.createProperty(6919 [createDecorator(Decorators.Event)],6920 [],6921 generator.createIdentifier("p3")6922 ),6923 ];6924 const stringValue = generator6925 .createVariableDeclaration(6926 generator.createObjectBindingPattern([6927 generator.createBindingElement(6928 undefined,6929 undefined,6930 generator.createIdentifier("p1")6931 ),6932 generator.createBindingElement(6933 undefined,6934 generator.createIdentifier("p3"),6935 generator.createIdentifier("_p3")6936 ),6937 ]),6938 undefined,6939 expression6940 )6941 .toString({6942 componentContext: generator.SyntaxKind.ThisKeyword,6943 newComponentContext: generator.SyntaxKind.ThisKeyword,6944 members: members,6945 });6946 assert.strictEqual(6947 getResult(stringValue),6948 getResult(`{p1, p3:_p3}=({p1:this.p1, p3:this._p3} as any)`)6949 );6950 });6951 mocha.it("Access TwoWay props - this.props.prop", function () {6952 const property = generator.createProperty(6953 [createDecorator(Decorators.TwoWay)],6954 [],6955 generator.createIdentifier("width"),6956 undefined,6957 undefined,6958 undefined6959 );6960 const expression = generator.createPropertyAccess(6961 generator.createPropertyAccess(6962 generator.createThis(),6963 generator.createIdentifier("props")6964 ),6965 generator.createIdentifier("width")6966 );6967 assert.strictEqual(6968 expression.toString({6969 members: [property],6970 componentContext: generator.SyntaxKind.ThisKeyword,6971 newComponentContext: generator.SyntaxKind.ThisKeyword,6972 }),6973 "this.width"6974 );6975 });6976 mocha.it("Call Event", function () {6977 const property = generator.createProperty(6978 [createDecorator(Decorators.Event)],6979 [],6980 generator.createIdentifier("onClick"),6981 undefined,6982 undefined,6983 undefined6984 );6985 const expression = generator.createCall(6986 generator.createPropertyAccess(6987 generator.createPropertyAccess(6988 generator.createThis(),6989 generator.createIdentifier("props")6990 ),6991 generator.createIdentifier("onClick")6992 ),6993 [],6994 [generator.createNumericLiteral("10")]6995 );6996 assert.strictEqual(6997 expression.toString({6998 members: [property],6999 componentContext: generator.SyntaxKind.ThisKeyword,7000 newComponentContext: generator.SyntaxKind.ThisKeyword,7001 }),7002 "this._onClick(10)"7003 );7004 });7005 mocha.it("Set TwoWay Prop", function () {7006 const property = generator.createProperty(7007 [createDecorator(Decorators.TwoWay)],7008 [],7009 generator.createIdentifier("width"),7010 undefined,7011 undefined,7012 undefined7013 );7014 const expression = generator.createBinary(7015 generator.createPropertyAccess(7016 generator.createPropertyAccess(7017 generator.createThis(),7018 generator.createIdentifier("props")7019 ),7020 generator.createIdentifier("width")7021 ),7022 generator.SyntaxKind.EqualsToken,7023 generator.createNumericLiteral("10")7024 );7025 assert.strictEqual(7026 getResult(7027 expression.toString({7028 members: [property],7029 componentContext: generator.SyntaxKind.ThisKeyword,7030 newComponentContext: generator.SyntaxKind.ThisKeyword,7031 })7032 ),7033 getResult("this._widthChange(this.width=10)")7034 );7035 });7036 mocha.it("Can't set OneWay Prop", function () {7037 const property = generator.createProperty(7038 [createDecorator(Decorators.OneWay)],7039 [],7040 generator.createIdentifier("width"),7041 undefined,7042 undefined,7043 undefined7044 );7045 const expression = generator.createBinary(7046 generator.createPropertyAccess(7047 generator.createPropertyAccess(7048 generator.createThis(),7049 generator.createIdentifier("props")7050 ),7051 generator.createIdentifier("width")7052 ),7053 generator.SyntaxKind.EqualsToken,7054 generator.createNumericLiteral("10")7055 );7056 let error = null;7057 try {7058 expression.toString({7059 componentContext: generator.SyntaxKind.ThisKeyword,7060 newComponentContext: generator.SyntaxKind.ThisKeyword,7061 members: [property],7062 });7063 } catch (e) {7064 error = e;7065 }7066 assert.strictEqual(7067 error,7068 "Error: Can't assign property use TwoWay, Internal State, Ref, ForwardRef prop - this.props.width = 10"7069 );7070 });7071 mocha.it("Can't set OneWay Prop (using unary)", function () {7072 const property = generator.createProperty(7073 [createDecorator(Decorators.OneWay)],7074 [],7075 generator.createIdentifier("width")7076 );7077 const expression = generator.createPostfix(7078 generator.createPropertyAccess(7079 generator.createPropertyAccess(7080 generator.createThis(),7081 generator.createIdentifier("props")7082 ),7083 generator.createIdentifier("width")7084 ),7085 generator.SyntaxKind.PlusPlusToken7086 );7087 let error = null;7088 try {7089 expression.toString({7090 componentContext: generator.SyntaxKind.ThisKeyword,7091 newComponentContext: generator.SyntaxKind.ThisKeyword,7092 members: [property],7093 });7094 } catch (e) {7095 error = e;7096 }7097 assert.strictEqual(7098 error,7099 "Error: Can't assign property use TwoWay() or Internal State - this.props.width++"7100 );7101 });7102 mocha.it("Access elementRef", function () {7103 const property = generator.createProperty(7104 [createDecorator(Decorators.Ref)],7105 [],7106 generator.createIdentifier("div"),7107 undefined,7108 generator.createUnionTypeNode([7109 generator.createKeywordTypeNode("HTMLDivElement"),7110 generator.createKeywordTypeNode("undefined"),7111 ])7112 );7113 const propertyWithExclamation = generator.createProperty(7114 [createDecorator(Decorators.Ref)],7115 [],7116 generator.createIdentifier("div"),7117 generator.SyntaxKind.ExclamationToken,7118 generator.createKeywordTypeNode("HTMLSpanElement")7119 );7120 const propertyWithQuestion = generator.createProperty(7121 [createDecorator(Decorators.Ref)],7122 [],7123 generator.createIdentifier("div"),7124 generator.SyntaxKind.QuestionToken,7125 generator.createKeywordTypeNode("HTMLDivElement")7126 );7127 const expression = generator.createPropertyAccess(7128 generator.createPropertyAccess(7129 generator.createThis(),7130 generator.createIdentifier("div")7131 ),7132 generator.createIdentifier("current")7133 );7134 const svgElement = generator.createProperty(7135 [createDecorator(Decorators.Ref)],7136 [],7137 generator.createIdentifier("div"),7138 undefined,7139 generator.createKeywordTypeNode("SVGGraphicsElement")7140 );7141 const element = generator.createProperty(7142 [createDecorator(Decorators.Ref)],7143 [],7144 generator.createIdentifier("div"),7145 undefined,7146 generator.createKeywordTypeNode("Element")7147 );7148 assert.strictEqual(7149 expression.toString({7150 members: [property],7151 componentContext: generator.SyntaxKind.ThisKeyword,7152 newComponentContext: generator.SyntaxKind.ThisKeyword,7153 }),7154 "this.div.nativeElement"7155 );7156 assert.strictEqual(7157 expression.toString({7158 members: [propertyWithExclamation],7159 componentContext: generator.SyntaxKind.ThisKeyword,7160 newComponentContext: generator.SyntaxKind.ThisKeyword,7161 }),7162 "this.div.nativeElement"7163 );7164 assert.strictEqual(7165 expression.toString({7166 members: [propertyWithQuestion],7167 componentContext: generator.SyntaxKind.ThisKeyword,7168 newComponentContext: generator.SyntaxKind.ThisKeyword,7169 }),7170 "this.div.nativeElement"7171 );7172 assert.strictEqual(7173 expression.toString({7174 members: [svgElement],7175 componentContext: generator.SyntaxKind.ThisKeyword,7176 newComponentContext: generator.SyntaxKind.ThisKeyword,7177 }),7178 "this.div.nativeElement"7179 );7180 assert.strictEqual(7181 expression.toString({7182 members: [element],7183 componentContext: generator.SyntaxKind.ThisKeyword,7184 newComponentContext: generator.SyntaxKind.ThisKeyword,7185 }),7186 "this.div.nativeElement"7187 );7188 });7189 mocha.it("Access ref object", function () {7190 const property = generator.createProperty(7191 [createDecorator(Decorators.Ref)],7192 [],7193 generator.createIdentifier("div"),7194 undefined,7195 generator.createUnionTypeNode([7196 generator.createKeywordTypeNode("HTMLDivElement"),7197 generator.createKeywordTypeNode("undefined"),7198 ])7199 );7200 const expression = generator.createPropertyAccess(7201 generator.createThis(),7202 generator.createIdentifier("div")7203 );7204 assert.strictEqual(7205 expression.toString({7206 members: [property],7207 componentContext: generator.SyntaxKind.ThisKeyword,7208 newComponentContext: generator.SyntaxKind.ThisKeyword,7209 }),7210 "this.div"7211 );7212 });7213 });7214 mocha.describe("Compile useEffect", function () {7215 this.beforeEach(function () {7216 this.effect = generator.createMethod(7217 [createDecorator("Effect")],7218 [],7219 undefined,7220 generator.createIdentifier("e"),7221 undefined,7222 undefined,7223 [],7224 undefined,7225 generator.createBlock([], true)7226 );7227 });7228 mocha.it(7229 "should generate schedule effect method and fill ngOnChanges if there is prop in dependency",7230 function () {7231 this.effect.body = generator.createBlock(7232 [7233 generator.createPropertyAccess(7234 generator.createThis(),7235 generator.createIdentifier("p")7236 ),7237 generator.createPropertyAccess(7238 generator.createThis(),7239 generator.createIdentifier("p2")7240 ),7241 ],7242 false7243 );7244 const component = createComponent(7245 ["p", "p1", "p2"]7246 .map((name) =>7247 generator.createProperty(7248 [createDecorator(Decorators.OneWay)],7249 undefined,7250 generator.createIdentifier(name),7251 undefined,7252 undefined,7253 undefined7254 )7255 )7256 .concat(this.effect)7257 ) as AngularComponent;7258 const ngOnChanges: string[] = [];7259 assert.strictEqual(7260 getResult(component.compileEffects([], [], ngOnChanges, [], [])),7261 getResult(`7262 __destroyEffects: any[] = [];7263 __viewCheckedSubscribeEvent: Array<(()=>void)|null> = [];7264 _effectTimeout: any;7265 __schedule_e(){7266 this.__destroyEffects[0]?.();7267 this.__viewCheckedSubscribeEvent[0] = ()=>{7268 this.__destroyEffects[0] = this.__e()7269 }7270 }7271 7272 _updateEffects(){7273 if(this.__viewCheckedSubscribeEvent.length){7274 clearTimeout(this._effectTimeout);7275 this._effectTimeout = setTimeout(()=>{7276 this.__viewCheckedSubscribeEvent.forEach((s, i)=>{7277 s?.();7278 if(this.__viewCheckedSubscribeEvent[i]===s){7279 this.__viewCheckedSubscribeEvent[i]=null;7280 }7281 });7282 });7283 }7284 }7285 `)7286 );7287 assert.strictEqual(7288 removeSpaces(ngOnChanges.join("\n")),7289 removeSpaces(`7290 if (this.__destroyEffects.length && ["p", "p2"].some(d=>changes[d])) {7291 this.__schedule_e();7292 }7293 `)7294 );7295 }7296 );7297 mocha.it(7298 "should generate schedule effect method and fill ngOnChanges all props in dependency",7299 function () {7300 this.effect.body = generator.createBlock(7301 [7302 generator.createPropertyAccess(7303 generator.createThis(),7304 generator.createIdentifier("props")7305 ),7306 ],7307 false7308 );7309 const component = createComponent(7310 ["p", "p1", "p2"]7311 .map((name) =>7312 generator.createProperty(7313 [createDecorator(Decorators.OneWay)],7314 undefined,7315 generator.createIdentifier(name),7316 undefined,7317 undefined,7318 undefined7319 )7320 )7321 .concat(this.effect)7322 ) as AngularComponent;7323 const ngOnChanges: string[] = [];7324 assert.strictEqual(7325 getResult(component.compileEffects([], [], ngOnChanges, [], [])),7326 getResult(`7327 __destroyEffects: any[] = [];7328 __viewCheckedSubscribeEvent: Array<(()=>void) | null> = [];7329 _effectTimeout: any;7330 __schedule_e(){7331 this.__destroyEffects[0]?.();7332 this.__viewCheckedSubscribeEvent[0] = ()=>{7333 this.__destroyEffects[0] = this.__e()7334 }7335 }7336 _updateEffects(){7337 if(this.__viewCheckedSubscribeEvent.length){7338 clearTimeout(this._effectTimeout);7339 this._effectTimeout = setTimeout(()=>{7340 this.__viewCheckedSubscribeEvent.forEach((s, i)=>{7341 s?.();7342 if(this.__viewCheckedSubscribeEvent[i]===s){7343 this.__viewCheckedSubscribeEvent[i]=null;7344 }7345 });7346 });7347 }7348 }7349 `)7350 );7351 assert.strictEqual(7352 getResult(ngOnChanges.join("\n")),7353 getResult(`7354 if (this.__destroyEffects.length) {7355 this.__schedule_e();7356 }7357 `)7358 );7359 }7360 );7361 mocha.it(7362 "should generate schedule effect method if there is internal state in dependency",7363 function () {7364 this.effect.body = generator.createBlock(7365 [7366 generator.createPropertyAccess(7367 generator.createThis(),7368 generator.createIdentifier("p")7369 ),7370 generator.createPropertyAccess(7371 generator.createThis(),7372 generator.createIdentifier("p2")7373 ),7374 ],7375 false7376 );7377 const component = createComponent(7378 ["p", "p1"]7379 .map((name) =>7380 generator.createProperty(7381 [createDecorator("InternalState")],7382 undefined,7383 generator.createIdentifier(name),7384 undefined,7385 undefined,7386 undefined7387 )7388 )7389 .concat([7390 generator.createProperty(7391 [],7392 undefined,7393 generator.createIdentifier("p2"),7394 undefined,7395 undefined,7396 undefined7397 ),7398 ])7399 .concat(this.effect)7400 ) as AngularComponent;7401 const ngOnChanges: string[] = [];7402 assert.strictEqual(7403 getResult(component.compileEffects([], [], ngOnChanges, [], [])),7404 getResult(`7405 __destroyEffects: any[] = [];7406 __viewCheckedSubscribeEvent: Array<(()=>void) | null> = [];7407 _effectTimeout: any;7408 __schedule_e(){7409 this.__destroyEffects[0]?.();7410 this.__viewCheckedSubscribeEvent[0] = ()=>{7411 this.__destroyEffects[0] = this.__e()7412 }7413 }7414 _updateEffects(){7415 if(this.__viewCheckedSubscribeEvent.length){7416 clearTimeout(this._effectTimeout);7417 this._effectTimeout = setTimeout(()=>{7418 this.__viewCheckedSubscribeEvent.forEach((s, i)=>{7419 s?.();7420 if(this.__viewCheckedSubscribeEvent[i]===s){7421 this.__viewCheckedSubscribeEvent[i]=null;7422 }7423 });7424 });7425 }7426 }7427 `)7428 );7429 assert.deepEqual(ngOnChanges, []);7430 const p1Setter = component.members.find((p) => p.name === "_p1");7431 assert.strictEqual(7432 getResult(p1Setter?.toString() || ""),7433 getResult(`set _p1(p1:any){7434 this.p1=p17435 this._detectChanges();7436 }`)7437 );7438 const p2Setter = component.members.find((p) => p.name === "_p2");7439 assert.strictEqual(7440 getResult(p2Setter?.toString() || ""),7441 getResult(`7442 set _p2(p2:any){7443 this.p2=p2;7444 this._detectChanges();7445 if (this.__destroyEffects.length) {7446 this.__schedule_e();7447 }7448 this._updateEffects();7449 }7450 `)7451 );7452 }7453 );7454 mocha.it(7455 "should not generate schedule effect method if there is not props in dependency",7456 function () {7457 const component = createComponent(7458 ["p", "p1"]7459 .map((name) =>7460 generator.createProperty(7461 [createDecorator(Decorators.OneWay)],7462 undefined,7463 generator.createIdentifier(name),7464 undefined,7465 undefined,7466 undefined7467 )7468 )7469 .concat(this.effect)7470 ) as AngularComponent;7471 const ngOnChanges: string[] = [];7472 assert.strictEqual(7473 getResult(component.compileEffects([], [], ngOnChanges, [], [])),7474 getResult(`7475 __destroyEffects: any[] = [];7476 __viewCheckedSubscribeEvent: Array<(()=>void) | null> = [];7477 _effectTimeout: any;7478 `)7479 );7480 assert.deepEqual(ngOnChanges, []);7481 }7482 );7483 });7484 mocha.describe("GetAccessor", function () {7485 mocha.it("add modifiers", function () {7486 const getter = generator.createGetAccessor(7487 [],7488 [7489 generator.SyntaxKind.PrivateKeyword,7490 generator.SyntaxKind.StaticKeyword,7491 ],7492 generator.createIdentifier("g"),7493 [],7494 undefined,7495 generator.createBlock([], false)7496 );7497 assert.strictEqual(7498 getResult(7499 getter.toString({7500 members: [getter],7501 })7502 ),7503 getResult(`private static get g(): any{}`)7504 );7505 });7506 mocha.describe("Memorize GetAccessor with complexType", function () {7507 function createGetAccessor(7508 type?: TypeExpression,7509 block?: Block,7510 name?: string7511 ) {7512 return generator.createGetAccessor(7513 [],7514 [],7515 generator.createIdentifier(name || "name"),7516 [],7517 type,7518 block ||7519 generator.createBlock(7520 [generator.createReturn(generator.createIdentifier("result"))],7521 true7522 )7523 );7524 }7525 mocha.it("Memorize Array type", function () {7526 const getter = createGetAccessor(7527 generator.createArrayTypeNode(7528 generator.createKeywordTypeNode("string")7529 )7530 );7531 assert.strictEqual(7532 getResult(getter.toString()),7533 getResult(`get name():string[]{7534 if(this.__getterCache["name"]!==undefined){7535 return this.__getterCache["name"]7536 }7537 7538 return this.__getterCache["name"]=( ():string[] => {7539 return result;7540 })();7541 }`)7542 );7543 assert.strictEqual(getter.isMemorized(), true);7544 });7545 mocha.it("Memorize createTypeLiteralNode", function () {7546 const getter = createGetAccessor(7547 generator.createTypeLiteralNode([7548 generator.createPropertySignature(7549 undefined,7550 generator.createIdentifier("field"),7551 undefined,7552 generator.createKeywordTypeNode(7553 generator.SyntaxKind.StringKeyword7554 ),7555 undefined7556 ),7557 ])7558 );7559 assert.strictEqual(getter.isMemorized(), true);7560 });7561 mocha.it("Memorize object", function () {7562 const getter = createGetAccessor(7563 generator.createKeywordTypeNode(generator.SyntaxKind.ObjectKeyword)7564 );7565 assert.strictEqual(getter.isMemorized(), true);7566 });7567 mocha.it("Do not memorize primitive type", function () {7568 const getter = createGetAccessor(7569 generator.createKeywordTypeNode("string")7570 );7571 assert.strictEqual(7572 getResult(getter.toString()),7573 getResult(`get name():string{7574 return result;7575 }`)7576 );7577 assert.strictEqual(getter.isMemorized(), false);7578 });7579 mocha.it("Do not memorize union with primitive type", function () {7580 const getter = createGetAccessor(7581 generator.createUnionTypeNode([7582 generator.createLiteralTypeNode(7583 generator.createStringLiteral("1")7584 ),7585 generator.createLiteralTypeNode(7586 generator.createStringLiteral("2")7587 ),7588 ])7589 );7590 assert.strictEqual(7591 getResult(getter.toString()),7592 getResult(`get name():'1'|'2'{7593 return result;7594 }`)7595 );7596 });7597 mocha.it("Memorize union with complex type", function () {7598 const getter = createGetAccessor(7599 generator.createUnionTypeNode([7600 generator.createLiteralTypeNode(7601 generator.createStringLiteral("1")7602 ),7603 generator.createLiteralTypeNode(7604 generator.createObjectLiteral([], false)7605 ),7606 ])7607 );7608 assert.strictEqual(7609 getResult(getter.toString()),7610 getResult(`get name():'1'|{}{7611 if(this.__getterCache["name"]!==undefined){7612 return this.__getterCache["name"];7613 }7614 7615 return this.__getterCache["name"]=( ():'1'|{} => {7616 return result;7617 })();7618 }`)7619 );7620 });7621 mocha.it("Memorize object literal type", function () {7622 const getter = createGetAccessor(7623 generator.createLiteralTypeNode(7624 generator.createObjectLiteral([], false)7625 )7626 );7627 assert.strictEqual(getter.isMemorized(), true);7628 assert.strictEqual(7629 getResult(getter.toString()),7630 getResult(`get name():{}{7631 if(this.__getterCache["name"]!==undefined){7632 return this.__getterCache["name"]7633 }7634 7635 return this.__getterCache["name"]=( ():{} => {7636 return result;7637 })();7638 }`)7639 );7640 });7641 mocha.describe("GetAccessor cache", function () {7642 mocha.it("Do not generate if simple type", function () {7643 const getter = createGetAccessor(7644 generator.createKeywordTypeNode("string")7645 );7646 const component = createComponent([getter]) as AngularComponent;7647 const ngOnChanges: string[] = [];7648 assert.strictEqual(component.compileGetterCache(ngOnChanges), "");7649 assert.deepEqual(ngOnChanges, []);7650 });7651 mocha.it(7652 "Create cache if component has getter with complex type",7653 function () {7654 const component = createComponent([7655 createGetAccessor(7656 generator.createArrayTypeNode(7657 generator.createKeywordTypeNode("string")7658 ),7659 undefined,7660 "g1"7661 ),7662 createGetAccessor(7663 generator.createArrayTypeNode(7664 generator.createKeywordTypeNode("number")7665 ),7666 undefined,7667 "g2"7668 ),7669 createGetAccessor(7670 generator.createKeywordTypeNode("number"),7671 undefined,7672 "g3"7673 ),7674 ]) as AngularComponent;7675 const ngOnChanges: string[] = [];7676 assert.strictEqual(7677 getResult(component.compileGetterCache(ngOnChanges)),7678 getResult(`__getterCache: {7679 g1?:string[];7680 g2?:number[];7681 } = {}`)7682 );7683 assert.deepEqual(ngOnChanges, []);7684 }7685 );7686 mocha.it(7687 "Fill ngOnChanges if getter has prop dependency",7688 function () {7689 const getter = createGetAccessor(7690 generator.createArrayTypeNode(7691 generator.createKeywordTypeNode("string")7692 ),7693 generator.createBlock(7694 [7695 generator.createPropertyAccess(7696 generator.createPropertyAccess(7697 generator.createThis(),7698 generator.createIdentifier("props")7699 ),7700 generator.createIdentifier("p")7701 ),7702 ],7703 false7704 )7705 );7706 const component = createComponent([7707 getter,7708 generator.createProperty(7709 [createDecorator(Decorators.OneWay)],7710 [],7711 generator.createIdentifier("p")7712 ),7713 ]) as AngularComponent;7714 const ngOnChanges: string[] = [];7715 assert.strictEqual(7716 getResult(component.compileGetterCache(ngOnChanges)),7717 getResult(`__getterCache: {7718 name?:string[];7719 } = {}`)7720 );7721 assert.strictEqual(7722 getResult(ngOnChanges.join("\n")),7723 getResult(`if(["p"].some(d=>changes[d])){7724 this.__getterCache[\"name\"] = undefined;7725 }`)7726 );7727 }7728 );7729 mocha.it("Reset cache on internal state setting", function () {7730 const getter = createGetAccessor(7731 generator.createArrayTypeNode(7732 generator.createKeywordTypeNode("string")7733 ),7734 generator.createBlock(7735 [7736 generator.createPropertyAccess(7737 generator.createThis(),7738 generator.createIdentifier("p")7739 ),7740 ],7741 false7742 )7743 );7744 const p = generator.createProperty(7745 [createDecorator(Decorators.InternalState)],7746 [],7747 generator.createIdentifier("p")7748 );7749 const p1 = generator.createProperty(7750 [createDecorator(Decorators.InternalState)],7751 [],7752 generator.createIdentifier("p1")7753 );7754 const component = createComponent([7755 getter,7756 p,7757 p1,7758 ]) as AngularComponent;7759 const ngOnChanges: string[] = [];7760 assert.strictEqual(7761 getResult(component.compileGetterCache(ngOnChanges)),7762 getResult(`__getterCache: {7763 name?:string[];7764 } = {}`)7765 );7766 assert.deepEqual(ngOnChanges, []);7767 assert.strictEqual(7768 getResult(7769 component.members.find((m) => m.name === "_p")!.toString()7770 ),7771 getResult(`7772 set _p(p:any){7773 this.p=p;7774 this._detectChanges();7775 this.__getterCache["name"] = undefined;7776 }`)7777 );7778 assert.strictEqual(7779 getResult(7780 component.members.find((m) => m.name === "_p1")!.toString()7781 ),7782 getResult(`7783 set _p1(p1:any){7784 this.p1=p1;7785 this._detectChanges();7786 }`)7787 );7788 });7789 mocha.it(7790 "Reset cache on ngChange if props in dependency",7791 function () {7792 const getter = createGetAccessor(7793 generator.createArrayTypeNode(7794 generator.createKeywordTypeNode("string")7795 ),7796 generator.createBlock(7797 [7798 generator.createPropertyAccess(7799 generator.createThis(),7800 generator.createIdentifier("props")7801 ),7802 ],7803 false7804 )7805 );7806 const component = createComponent([getter]) as AngularComponent;7807 const ngOnChanges: string[] = [];7808 component.compileGetterCache(ngOnChanges);7809 assert.deepEqual(7810 ngOnChanges.join("\n"),7811 `this.__getterCache["name"] = undefined;`7812 );7813 }7814 );7815 });7816 });7817 });7818 });7819 mocha.describe("Expressions", function () {7820 mocha.it("Variable declaration", function () {7821 assert.strictEqual(7822 generator7823 .createVariableDeclaration(7824 generator.createIdentifier("a"),7825 undefined,7826 undefined7827 )7828 .toString(),7829 "a"7830 );7831 assert.strictEqual(7832 generator7833 .createVariableDeclaration(7834 generator.createIdentifier("a"),7835 generator.createKeywordTypeNode("any"),7836 generator.createNumericLiteral("10")7837 )7838 .toString(),7839 "a:any=10"7840 );7841 });7842 mocha.it("createVariableStatement without initializer", function () {7843 assert.strictEqual(7844 generator7845 .createVariableStatement(7846 [],7847 generator.createVariableDeclarationList(7848 [7849 generator.createVariableDeclaration(7850 generator.createIdentifier("a")7851 ),7852 ],7853 generator.SyntaxKind.LetKeyword7854 )7855 )7856 .toString(),7857 " let a"7858 );7859 });7860 mocha.it("AsExpression", function () {7861 const prop = generator.createProperty(7862 [createDecorator(Decorators.OneWay)],7863 [],7864 generator.createIdentifier("p")7865 );7866 const expression = generator.createAsExpression(7867 generator.createPropertyAccess(7868 generator.createThis(),7869 generator.createIdentifier("p")7870 ),7871 generator.createKeywordTypeNode("number")7872 );7873 assert.strictEqual(expression.toString(), "this.p as number");7874 assert.strictEqual(7875 expression.toString({7876 members: [prop],7877 componentContext: "this",7878 newComponentContext: "",7879 }),7880 "p as number"7881 );7882 assert.strictEqual(7883 expression.toString({7884 members: [],7885 componentContext: "this",7886 newComponentContext: "",7887 disableTemplates: true,7888 }),7889 "p"7890 );7891 });7892 mocha.describe("NonNullExpression", function () {7893 mocha.it(7894 "NonNullExpression with this context - expression!",7895 function () {7896 const prop = generator.createProperty(7897 [createDecorator(Decorators.OneWay)],7898 [],7899 generator.createIdentifier("p")7900 );7901 const expression = generator.createNonNullExpression(7902 generator.createPropertyAccess(7903 generator.createThis(),7904 generator.createIdentifier("p")7905 )7906 );7907 assert.strictEqual(7908 expression.toString({7909 members: [prop],7910 componentContext: "this",7911 newComponentContext: "",7912 }),7913 "p!"7914 );7915 }7916 );7917 mocha.it("without options - expression!", function () {7918 const expression = generator.createNonNullExpression(7919 generator.createPropertyAccess(7920 generator.createThis(),7921 generator.createIdentifier("p")7922 )7923 );7924 assert.strictEqual(expression.toString(), "this.p!");7925 });7926 mocha.it("with non-this context - expression", function () {7927 const prop = generator.createProperty(7928 [createDecorator(Decorators.OneWay)],7929 [],7930 generator.createIdentifier("p")7931 );7932 const expression = generator.createNonNullExpression(7933 generator.createPropertyAccess(7934 generator.createIdentifier("viewModel"),7935 generator.createIdentifier("p")7936 )7937 );7938 assert.strictEqual(7939 expression.toString({7940 members: [prop],7941 componentContext: "viewModel",7942 newComponentContext: "",7943 }),7944 "p"7945 );7946 });7947 });7948 mocha.it("createPropertyAccessChain", function () {7949 const expression = generator.createPropertyAccessChain(7950 generator.createIdentifier("a"),7951 generator.createToken(generator.SyntaxKind.QuestionDotToken),7952 generator.createIdentifier("b")7953 );7954 assert.equal(expression.toString(), "a?.b");7955 assert.equal(7956 expression.toString({7957 members: [],7958 newComponentContext: "",7959 }),7960 "(a===undefined||a===null?undefined:a.b)"7961 );7962 assert.equal(7963 expression.toString({7964 members: [],7965 newComponentContext: generator.SyntaxKind.ThisKeyword,7966 }),7967 "a?.b"7968 );7969 });7970 mocha.it("empty jsx expression", function () {7971 const expression = generator.createJsxElement(7972 generator.createJsxOpeningElement(generator.createIdentifier("div")),7973 [generator.createJsxExpression(undefined, undefined)],7974 generator.createJsxClosingElement(generator.createIdentifier("div"))7975 );7976 assert.strictEqual(expression.toString(), "<div ></div>");7977 });7978 });...
vue-generator.test.ts
Source:vue-generator.test.ts
...19 mocha.describe("common", function () {20 mocha.it("NonNullExpression", function () {21 const expression = generator.createPropertyAccess(22 generator.createThis(),23 generator.createIdentifier("field")24 );25 assert.equal(26 generator.createNonNullExpression(expression).toString(),27 "this.field"28 );29 });30 mocha.it("createPropertyAccessChain", function () {31 const expression = generator.createPropertyAccessChain(32 generator.createIdentifier("a"),33 generator.createToken(generator.SyntaxKind.QuestionDotToken),34 generator.createIdentifier("b")35 );36 assert.equal(expression.toString(), "a?.b");37 assert.equal(38 expression.toString({39 members: [],40 newComponentContext: "",41 }),42 "(a===undefined||a===null?undefined:a.b)"43 );44 assert.equal(45 expression.toString({46 members: [],47 newComponentContext: generator.SyntaxKind.ThisKeyword,48 }),49 "a?.b"50 );51 });52 });53 mocha.describe(54 "Type expressions should generate empty string",55 function () {56 mocha.it("KeywordTypeNode", function () {57 assert.strictEqual(58 generator.createKeywordTypeNode("number").toString(),59 ""60 );61 });62 mocha.it("ArrayTypeNode", function () {63 assert.strictEqual(64 generator65 .createArrayTypeNode(generator.createKeywordTypeNode("number"))66 .toString(),67 ""68 );69 });70 mocha.it("ArrayTypeNode", function () {71 assert.strictEqual(72 generator73 .createArrayTypeNode(generator.createKeywordTypeNode("number"))74 .toString(),75 ""76 );77 });78 mocha.it("createLiteralTypeNode", function () {79 assert.strictEqual(80 generator81 .createLiteralTypeNode(generator.createStringLiteral("2"))82 .toString(),83 ""84 );85 });86 mocha.it("createIndexedAccessTypeNode", function () {87 const expression = generator.createIndexedAccessTypeNode(88 generator.createTypeReferenceNode(89 generator.createIdentifier("PageIndex"),90 undefined91 ),92 generator.createLiteralTypeNode(generator.createStringLiteral("1"))93 );94 assert.strictEqual(expression.toString(), "");95 });96 mocha.it("createIntersectionTypeNode", function () {97 assert.equal(98 generator.createIntersectionTypeNode([99 generator.createKeywordTypeNode("string"),100 generator.createKeywordTypeNode("number"),101 ]),102 ""103 );104 });105 mocha.it("createUnionTypeNode", function () {106 assert.equal(107 generator.createUnionTypeNode([108 generator.createKeywordTypeNode("string"),109 generator.createKeywordTypeNode("number"),110 ]),111 ""112 );113 });114 mocha.it("createParenthesizedType", function () {115 assert.equal(116 generator.createParenthesizedType(117 generator.createKeywordTypeNode("string")118 ),119 ""120 );121 });122 mocha.it("FunctionTypeNode", function () {123 assert.strictEqual(124 generator125 .createFunctionTypeNode(126 undefined,127 [],128 generator.createKeywordTypeNode("string")129 )130 .toString(),131 ""132 );133 });134 mocha.it("createTypeAliasDeclaration", function () {135 const literalNode = generator.createTypeLiteralNode([136 generator.createPropertySignature(137 [],138 generator.createIdentifier("b"),139 undefined,140 generator.createKeywordTypeNode("string")141 ),142 ]);143 const expression = generator.createTypeAliasDeclaration(144 undefined,145 ["export", "declare"],146 generator.createIdentifier("Name"),147 [],148 literalNode149 );150 assert.strictEqual(expression.toString(), "");151 });152 mocha.it("createTypeOperatorNode", function () {153 assert.equal(154 generator.createTypeOperatorNode(155 generator.createKeywordTypeNode("number")156 ),157 ""158 );159 });160 mocha.it("TypeReferenceNode", function () {161 const expression = generator.createTypeReferenceNode(162 generator.createIdentifier("NodeType"),163 undefined164 );165 assert.strictEqual(expression.toString(), "");166 });167 mocha.it("ArrowFunction with Token type should ignore it", function () {168 const expression = generator.createArrowFunction(169 undefined,170 undefined,171 [],172 generator.createToken(generator.SyntaxKind.VoidKeyword),173 generator.createToken(generator.SyntaxKind.EqualsGreaterThanToken),174 generator.createBlock([], true)175 );176 assert.strictEqual(getAst(expression.toString()), getAst("()=>{}"));177 });178 mocha.it(179 "ArrowFunction with defined typeParameters should ignore it",180 function () {181 const expression = generator.createArrowFunction(182 undefined,183 [184 generator.createTypeParameterDeclaration(185 generator.createIdentifier("SomeType")186 ),187 ],188 [],189 undefined,190 "",191 generator.createBlock([], true)192 );193 assert.strictEqual(getAst(expression.toString()), getAst("()=>{}"));194 }195 );196 mocha.it("Function with Token type should ignore it", function () {197 const expression = generator.createFunctionDeclaration(198 [],199 undefined,200 "",201 generator.createIdentifier("f"),202 undefined,203 [],204 generator.createToken(generator.SyntaxKind.VoidKeyword),205 generator.createBlock([], true)206 );207 assert.strictEqual(208 getAst(expression.toString()),209 getAst("function f(){}")210 );211 });212 mocha.it("InterfaceDeclaration", function () {213 const expression = generator.createInterfaceDeclaration(214 undefined,215 undefined,216 generator.createIdentifier("name"),217 undefined,218 undefined,219 []220 );221 assert.strictEqual(expression.toString(), "");222 });223 }224 );225 mocha.it("empty expression", function () {226 const expression = generator.createJsxElement(227 generator.createJsxOpeningElement(generator.createIdentifier("div")),228 [generator.createJsxExpression(undefined, undefined)],229 generator.createJsxClosingElement(generator.createIdentifier("div"))230 );231 assert.strictEqual(expression.toString(), "<div ></div>");232 });233 mocha.describe("Enum", function () {234 mocha.it("member", function () {235 const result = generator.createEnumMember(236 generator.createIdentifier("E1"),237 generator.createStringLiteral("test")238 );239 assert.equal(result.toString(), 'E1:"test"');240 });241 mocha.it("declaration", function () {242 const result = generator.createEnumDeclaration(243 [],244 ["export", "default"],245 generator.createIdentifier("MyEnum"),246 [247 generator.createEnumMember(generator.createIdentifier("E1")),248 generator.createEnumMember(249 generator.createIdentifier("E2"),250 generator.createStringLiteral("test1")251 ),252 generator.createEnumMember(253 generator.createIdentifier("E3"),254 generator.createStringLiteral("test2")255 ),256 generator.createEnumMember(257 generator.createIdentifier("E4"),258 generator.createNumericLiteral("10")259 ),260 generator.createEnumMember(generator.createIdentifier("E5")),261 ]262 );263 assert.strictEqual(264 getAst(result.toString()),265 getAst(`266 export default const MyEnum = {267 E1:0,268 E2:"test1",269 E3:"test2",270 E4:10,271 E5:11272 }273 `)274 );275 });276 mocha.it("empty declaration", function () {277 const result = generator.createEnumDeclaration(278 undefined,279 undefined,280 generator.createIdentifier("MyEnum"),281 []282 );283 assert.strictEqual(284 getAst(result.toString()),285 getAst("const MyEnum = {}")286 );287 });288 });289 mocha.describe("Import declaration", function () {290 mocha.it("import .d module should be ignored", function () {291 const expression = generator.createImportDeclaration(292 [],293 [],294 undefined,295 generator.createStringLiteral("../dirname/component.types.d")296 );297 assert.strictEqual(expression.toString(), "");298 });299 mocha.it("import type should be ignored", function () {300 const expression = generator.createImportDeclaration(301 [],302 [],303 generator.createImportClause(304 generator.createIdentifier("Type"),305 undefined,306 true307 ),308 generator.createStringLiteral("../dirname/component.types")309 );310 assert.strictEqual(expression.toString(), "");311 });312 });313 mocha.describe("generic types should be ignored", function () {314 mocha.it("createClassDeclaration generic class", function () {315 const genericClass = generator.createClassDeclaration(316 undefined,317 undefined,318 new Identifier("GenericClass"),319 ["T"],320 [],321 []322 );323 assert.strictEqual(324 getAst(genericClass.toString()),325 getAst(`class GenericClass{326 }`)327 );328 });329 mocha.it(330 "createClassDeclaration generic class with heritable",331 function () {332 const genericClass = generator.createClassDeclaration(333 undefined,334 undefined,335 new Identifier("GenericClass"),336 ["T", "S"],337 [338 generator.createHeritageClause(339 generator.SyntaxKind.ExtendsKeyword,340 [341 generator.createExpressionWithTypeArguments(342 [343 generator.createTypeReferenceNode(344 generator.createIdentifier("T"),345 undefined346 ),347 ],348 generator.createIdentifier("PluginEntity")349 ),350 ]351 ),352 ],353 []354 );355 assert.strictEqual(356 getAst(genericClass.toString()),357 getAst(`358 class GenericClass extends PluginEntity {359 }`)360 );361 }362 );363 mocha.it("create generic function with generic return", function () {364 const genericFunction = generator.createFunctionDeclaration(365 undefined,366 [generator.createModifier(generator.SyntaxKind.ExportKeyword)],367 "",368 generator.createIdentifier("createValue"),369 [370 generator.createTypeParameterDeclaration(371 generator.createIdentifier("T"),372 undefined,373 undefined374 ),375 ],376 [],377 generator.createTypeReferenceNode(378 generator.createIdentifier("PluginEntity"),379 [380 generator.createTypeReferenceNode(381 generator.createIdentifier("T"),382 undefined383 ),384 generator.createTypeReferenceNode(385 generator.createIdentifier("T"),386 undefined387 ),388 ]389 ),390 generator.createBlock(391 [392 generator.createReturn(393 generator.createNew(394 generator.createIdentifier("PluginEntity"),395 [396 generator.createTypeReferenceNode(397 generator.createIdentifier("T"),398 undefined399 ),400 generator.createTypeReferenceNode(401 generator.createIdentifier("T"),402 undefined403 ),404 ],405 []406 )407 ),408 ],409 true410 )411 );412 assert.strictEqual(413 getAst(genericFunction.toString()),414 getAst(`415 export function createValue() {416 return new PluginEntity();417 }`)418 );419 });420 });421 });422 mocha.describe("Property", function () {423 const name = generator.createIdentifier("p");424 mocha.describe("Props", function () {425 const decorators = [createDecorator("OneWay")];426 mocha.describe("types", function () {427 mocha.it("Property with KeywordTypeNode", function () {428 const expression = generator.createProperty(429 decorators,430 undefined,431 name,432 generator.SyntaxKind.QuestionToken,433 generator.createKeywordTypeNode("string"),434 undefined435 );436 assert.strictEqual(437 getAst(expression.toString({ members: [] })),438 getAst("p: {type: String}")439 );440 assert.strictEqual(expression.getter(), "p");441 assert.strictEqual(expression.getter("this"), "this.p");442 });443 mocha.it("Property with KeywordTypeNode - any", function () {444 const expression = generator.createProperty(445 decorators,446 undefined,447 name,448 generator.SyntaxKind.QuestionToken,449 generator.createKeywordTypeNode("any"),450 undefined451 );452 assert.strictEqual(453 getAst(expression.toString({ members: [] })),454 getAst("p: {}")455 );456 });457 mocha.it("Property with KeywordTypeNode - undefined", function () {458 const expression = generator.createProperty(459 decorators,460 undefined,461 name,462 generator.SyntaxKind.QuestionToken,463 generator.createKeywordTypeNode("undefined"),464 undefined465 );466 assert.strictEqual(467 getAst(expression.toString({ members: [] })),468 getAst("p: {}")469 );470 assert.strictEqual(expression.getter(), "p");471 assert.strictEqual(expression.getter("this"), "this.p");472 });473 mocha.it("Property with ArrayTypeNode", function () {474 const expression = generator.createProperty(475 decorators,476 undefined,477 name,478 undefined,479 generator.createArrayTypeNode(480 generator.createKeywordTypeNode("string")481 ),482 undefined483 );484 assert.strictEqual(485 getAst(expression.toString({ members: [] })),486 getAst("p: {type: Array}")487 );488 });489 mocha.it("Property with Function type", function () {490 const expression = generator.createProperty(491 decorators,492 undefined,493 name,494 undefined,495 generator.createFunctionTypeNode(496 undefined,497 [],498 generator.createKeywordTypeNode("string")499 ),500 undefined501 );502 assert.strictEqual(503 getAst(expression.toString({ members: [] })),504 getAst("p: {type: Function")505 );506 });507 mocha.it("Property with array as TypeReferenceNode", function () {508 const expression = generator.createProperty(509 decorators,510 undefined,511 name,512 undefined,513 generator.createTypeReferenceNode(514 generator.createIdentifier("Array"),515 [generator.createKeywordTypeNode("Number")]516 ),517 undefined518 );519 assert.strictEqual(520 getAst(expression.toString({ members: [] })),521 getAst("p: {type: Array")522 );523 });524 mocha.it("Property with custom TypeReferenceNode", function () {525 const expression = generator.createProperty(526 decorators,527 undefined,528 name,529 undefined,530 generator.createTypeReferenceNode(531 generator.createIdentifier("CustomType")532 ),533 undefined534 );535 assert.strictEqual(536 getAst(expression.toString({ members: [] })),537 getAst("p: {type: Object")538 );539 });540 mocha.it("Property with *Element type", function () {541 const elementTypes = [542 "Element",543 "HTMLElement",544 "HTMLDivElement",545 "SVGElement",546 ];547 elementTypes.forEach((type) => {548 const expression = generator.createProperty(549 decorators,550 undefined,551 name,552 undefined,553 generator.createTypeReferenceNode(554 generator.createIdentifier(type)555 ),556 undefined557 );558 assert.strictEqual(559 getAst(expression.toString({ members: [] })),560 getAst(`p: {type: ${type}`)561 );562 });563 });564 mocha.it("Property has Boolean type without initializer", function () {565 const expression = generator.createProperty(566 decorators,567 undefined,568 name,569 undefined,570 generator.createUnionTypeNode([571 generator.createKeywordTypeNode(572 generator.SyntaxKind.BooleanKeyword573 ),574 generator.createKeywordTypeNode(575 generator.SyntaxKind.NumberKeyword576 ),577 ]),578 undefined579 );580 assert.strictEqual(581 getAst(expression.toString({ members: [] })),582 getAst(`p: {583 type: [Boolean, Number],584 default(){585 return undefined586 }587 }`)588 );589 });590 mocha.it("Property has Boolean type with initializer", function () {591 const expression = generator.createProperty(592 decorators,593 undefined,594 name,595 undefined,596 generator.createUnionTypeNode([597 generator.createKeywordTypeNode(598 generator.SyntaxKind.BooleanKeyword599 ),600 generator.createKeywordTypeNode(601 generator.SyntaxKind.NumberKeyword602 ),603 ]),604 generator.createFalse()605 );606 assert.strictEqual(607 getAst(expression.toString({ members: [] })),608 getAst(`p: {609 type: [Boolean, Number],610 default(){611 return false612 }613 }`)614 );615 });616 mocha.describe("Property with LiteralTypeNode", function () {617 mocha.it("Object", function () {618 const expression = generator.createProperty(619 decorators,620 undefined,621 name,622 undefined,623 generator.createLiteralTypeNode(624 generator.createObjectLiteral([], false)625 ),626 undefined627 );628 assert.strictEqual(629 getAst(expression.toString({ members: [] })),630 getAst("p: {type: Object}")631 );632 });633 mocha.it("string", function () {634 const expression = generator.createProperty(635 decorators,636 undefined,637 name,638 undefined,639 generator.createLiteralTypeNode(640 generator.createStringLiteral("10")641 ),642 undefined643 );644 assert.strictEqual(645 getAst(expression.toString({ members: [] })),646 getAst("p: {type: String}")647 );648 });649 mocha.it("number", function () {650 const expression = generator.createProperty(651 decorators,652 undefined,653 name,654 undefined,655 generator.createLiteralTypeNode(656 generator.createNumericLiteral("10")657 ),658 undefined659 );660 assert.strictEqual(661 getAst(expression.toString({ members: [] })),662 getAst("p: {type: Number}")663 );664 });665 });666 mocha.describe("Union", function () {667 mocha.it("Property with Union type", function () {668 const expression = generator.createProperty(669 decorators,670 undefined,671 name,672 undefined,673 generator.createUnionTypeNode([674 generator.createKeywordTypeNode("string"),675 generator.createKeywordTypeNode("number"),676 ]),677 undefined678 );679 assert.strictEqual(680 getAst(expression.toString({ members: [] })),681 getAst("p: {type: [String,Number]}")682 );683 });684 mocha.it("Property with Union type with undefined", function () {685 const expression = generator.createProperty(686 decorators,687 undefined,688 name,689 undefined,690 generator.createUnionTypeNode([691 generator.createKeywordTypeNode("string"),692 generator.createKeywordTypeNode("undefined"),693 ]),694 undefined695 );696 assert.strictEqual(697 getAst(expression.toString({ members: [] })),698 getAst("p: {type: [String]}")699 );700 });701 mocha.it("type should not have duplicates", function () {702 const expression = generator.createProperty(703 decorators,704 undefined,705 name,706 undefined,707 generator.createUnionTypeNode([708 generator.createLiteralTypeNode(709 generator.createStringLiteral("10")710 ),711 generator.createLiteralTypeNode(712 generator.createStringLiteral("11")713 ),714 generator.createLiteralTypeNode(715 generator.createNumericLiteral("12")716 ),717 ]),718 undefined719 );720 assert.strictEqual(721 getAst(expression.toString({ members: [] })),722 getAst("p: {type: [String, Number]}")723 );724 });725 mocha.it(726 "type should be an array if only one type in the union",727 function () {728 const expression = generator.createProperty(729 decorators,730 undefined,731 name,732 undefined,733 generator.createUnionTypeNode([734 generator.createLiteralTypeNode(735 generator.createStringLiteral("10")736 ),737 generator.createLiteralTypeNode(738 generator.createStringLiteral("11")739 ),740 generator.createLiteralTypeNode(741 generator.createStringLiteral("12")742 ),743 ]),744 undefined745 );746 assert.strictEqual(747 getAst(expression.toString({ members: [] })),748 getAst("p: {type: String}")749 );750 }751 );752 });753 mocha.it("Property without type", function () {754 const expression = generator.createProperty(755 decorators,756 undefined,757 name,758 undefined,759 undefined,760 undefined761 );762 assert.strictEqual(763 getAst(expression.toString({ members: [] })),764 getAst("p: {}")765 );766 });767 });768 mocha.it("Required property", function () {769 const expression = generator.createProperty(770 decorators,771 undefined,772 name,773 generator.SyntaxKind.ExclamationToken,774 generator.createKeywordTypeNode("string"),775 undefined776 );777 assert.strictEqual(778 getAst(expression.toString({ members: [] })),779 getAst(`p: {780 type: String,781 required: true782 }`)783 );784 });785 mocha.it("Property with initializer - number", function () {786 const expression = generator.createProperty(787 decorators,788 undefined,789 name,790 undefined,791 undefined,792 generator.createNumericLiteral("10")793 );794 assert.strictEqual(795 getAst(expression.toString({ members: [] })),796 getAst(`p: { 797 type: Number,798 default(){799 return 10;800 }}`)801 );802 });803 mocha.it("Property with initializer - string", function () {804 const expression = generator.createProperty(805 decorators,806 undefined,807 name,808 undefined,809 undefined,810 generator.createStringLiteral("10")811 );812 assert.strictEqual(813 getAst(expression.toString({ members: [] })),814 getAst(`p: { 815 type: String,816 default(){817 return "10";818 }}`)819 );820 });821 mocha.it("Property with initializer - function", function () {822 const expression = generator.createProperty(823 decorators,824 undefined,825 name,826 undefined,827 generator.createFunctionTypeNode(828 undefined,829 [],830 generator.createKeywordTypeNode("string")831 ),832 generator.createArrowFunction(833 [],834 [],835 [],836 undefined,837 generator.SyntaxKind.EqualsGreaterThanToken,838 generator.createNull()839 )840 );841 assert.strictEqual(842 getAst(expression.toString({ members: [] })),843 getAst(`p: { 844 type: Function,845 default: () => null846 }`)847 );848 });849 mocha.describe("Slots", function () {850 mocha.it("default slot", function () {851 const expression = generator.createProperty(852 [createDecorator("Slot")],853 undefined,854 name,855 generator.SyntaxKind.QuestionToken,856 generator.createKeywordTypeNode("boolean"),857 generator.createTrue()858 );859 assert.strictEqual(expression.toString({ members: [] }), "");860 assert.strictEqual(expression.getter("this"), "this.$slots.p");861 });862 mocha.it("default slot", function () {863 const expression = generator.createProperty(864 [createDecorator("Slot")],865 undefined,866 generator.createIdentifier("default"),867 generator.SyntaxKind.QuestionToken,868 generator.createKeywordTypeNode("boolean"),869 generator.createTrue()870 );871 assert.strictEqual(expression.toString({ members: [] }), "");872 assert.strictEqual(expression.getter("this"), "this.$slots.default");873 });874 mocha.it("children slot", function () {875 const expression = generator.createProperty(876 [createDecorator("Slot")],877 undefined,878 generator.createIdentifier("children"),879 generator.SyntaxKind.QuestionToken,880 generator.createKeywordTypeNode("boolean"),881 generator.createTrue()882 );883 assert.strictEqual(expression.toString({ members: [] }), "");884 assert.strictEqual(expression.getter("this"), "this.$slots.default");885 });886 });887 mocha.describe("Template", function () {888 mocha.it(889 "Template props toString should return empty string",890 function () {891 const expression = generator.createProperty(892 [createDecorator("Template")],893 undefined,894 name,895 generator.SyntaxKind.QuestionToken,896 generator.createKeywordTypeNode("boolean"),897 generator.createTrue()898 );899 assert.strictEqual(expression.toString({ members: [] }), "");900 }901 );902 });903 });904 mocha.describe("Internal state", function () {905 const decorators = [createDecorator("InternalState")];906 mocha.it("without initializer", function () {907 const expression = generator.createProperty(908 decorators,909 undefined,910 name,911 generator.SyntaxKind.QuestionToken,912 generator.createKeywordTypeNode("string"),913 undefined914 );915 assert.strictEqual(916 getAst(expression.toString({ members: [] })),917 getAst("p: undefined")918 );919 assert.strictEqual(expression.getter(), "p");920 });921 mocha.it("with initializer", function () {922 const expression = generator.createProperty(923 decorators,924 undefined,925 name,926 generator.SyntaxKind.QuestionToken,927 generator.createKeywordTypeNode("string"),928 generator.createNumericLiteral("10")929 );930 assert.strictEqual(931 getAst(expression.toString({ members: [] })),932 getAst("p: 10")933 );934 });935 });936 mocha.describe("Event", function () {937 mocha.it("toString should return empty string", function () {938 const expression = generator.createProperty(939 [createDecorator("Event")],940 undefined,941 name,942 generator.SyntaxKind.QuestionToken,943 generator.createKeywordTypeNode("function"),944 undefined945 );946 assert.strictEqual(expression.toString({ members: [] }), "");947 });948 });949 mocha.describe("Refs", function () {950 mocha.it("toString should return empty string", function () {951 const expression = generator.createProperty(952 [createDecorator("Ref")],953 undefined,954 name,955 generator.SyntaxKind.QuestionToken,956 generator.createKeywordTypeNode("HtmlDivElement"),957 undefined958 );959 assert.strictEqual(expression.toString({ members: [] }), "");960 });961 mocha.it("getter", function () {962 const expression = generator.createProperty(963 [createDecorator("Ref")],964 undefined,965 name,966 generator.SyntaxKind.QuestionToken,967 generator.createKeywordTypeNode("HtmlDivElement"),968 undefined969 );970 assert.strictEqual(expression.getter("this"), "this.$refs.p");971 assert.strictEqual(expression.getter(""), "p");972 });973 });974 });975 mocha.describe("Call", function () {976 mocha.it("Call with typeParameter", function () {977 assert.equal(978 generator979 .createCall(980 generator.createIdentifier("a"),981 [982 generator.createTypeParameterDeclaration(983 generator.createIdentifier("TypeParameter")984 ),985 ],986 []987 )988 .toString(),989 "a()"990 );991 });992 mocha.it("CallChain with typeParameter", function () {993 assert.equal(994 generator995 .createCallChain(996 generator.createIdentifier("a"),997 generator.SyntaxKind.QuestionDotToken,998 [999 generator.createTypeParameterDeclaration(1000 generator.createIdentifier("TypeParameter")1001 ),1002 ],1003 []1004 )1005 .toString(),1006 "a?.()"1007 );1008 });1009 mocha.it("Call expression generates usual call if not event", function () {1010 assert.equal(1011 generator1012 .createCall(generator.createIdentifier("a"), undefined, [1013 generator.createNumericLiteral("10"),1014 ])1015 .toString(),1016 "a(10)"1017 );1018 });1019 mocha.it("Call expression generates emit if call Event", function () {1020 const member = generator.createProperty(1021 [createDecorator("Event")],1022 undefined,1023 generator.createIdentifier("onClick")1024 );1025 assert.strictEqual(1026 generator1027 .createCall(1028 generator.createPropertyAccess(1029 generator.createThis(),1030 generator.createIdentifier("onClick")1031 ),1032 undefined,1033 [generator.createNumericLiteral("10")]1034 )1035 .toString({1036 members: [member],1037 componentContext: "this",1038 newComponentContext: "this",1039 }),1040 "this.onClick(10)"1041 );1042 });1043 mocha.it("CallChain expression generates emit if call Event", function () {1044 const member = generator.createProperty(1045 [createDecorator("Event")],1046 undefined,1047 generator.createIdentifier("onClick")1048 );1049 assert.strictEqual(1050 generator1051 .createCallChain(1052 generator.createPropertyAccess(1053 generator.createThis(),1054 generator.createIdentifier("onClick")1055 ),1056 generator.SyntaxKind.QuestionDotToken,1057 undefined,1058 [generator.createNumericLiteral("10")]1059 )1060 .toString({1061 members: [member],1062 componentContext: "this",1063 newComponentContext: "this",1064 }),1065 "this.onClick(10)"1066 );1067 });1068 mocha.it("CallChain Identifer that is call event", function () {1069 const member = generator.createProperty(1070 [createDecorator("Event")],1071 undefined,1072 generator.createIdentifier("onClick")1073 );1074 assert.strictEqual(1075 generator1076 .createCallChain(1077 generator.createIdentifier("click"),1078 generator.SyntaxKind.QuestionDotToken,1079 undefined,1080 [generator.createNumericLiteral("10")]1081 )1082 .toString({1083 members: [member],1084 componentContext: "this",1085 newComponentContext: "this",1086 variables: {1087 click: generator.createPropertyAccess(1088 generator.createThis(),1089 generator.createIdentifier("onClick")1090 ),1091 },1092 }),1093 "this.onClick(10)"1094 );1095 });1096 mocha.it(1097 "CallChain expression generates usual call if not event",1098 function () {1099 assert.strictEqual(1100 generator1101 .createCallChain(1102 generator.createIdentifier("a"),1103 generator.SyntaxKind.QuestionDotToken,1104 undefined,1105 [generator.createNumericLiteral("10")]1106 )1107 .toString(),1108 "a?.(10)"1109 );1110 }1111 );1112 });1113 mocha.describe("Methods", function () {1114 mocha.it("Method with options", function () {1115 const expression = generator.createMethod(1116 [createDecorator("SomeDecorator")],1117 ["public"],1118 undefined,1119 generator.createIdentifier("m"),1120 undefined,1121 undefined,1122 [],1123 undefined,1124 generator.createBlock([], false)1125 );1126 assert.strictEqual(1127 getAst(1128 expression.toString({1129 members: [],1130 })1131 ),1132 getAst("m(){}")1133 );1134 });1135 mocha.it("Method with parameters", function () {1136 const expression = generator.createMethod(1137 [],1138 [],1139 undefined,1140 generator.createIdentifier("m"),1141 undefined,1142 undefined,1143 [1144 generator.createParameter(1145 [],1146 [],1147 undefined,1148 generator.createIdentifier("p1"),1149 generator.SyntaxKind.QuestionToken,1150 generator.createKeywordTypeNode("number"),1151 generator.createNumericLiteral("10")1152 ),1153 generator.createParameter(1154 [],1155 [],1156 undefined,1157 generator.createIdentifier("p2"),1158 generator.SyntaxKind.QuestionToken,1159 generator.createKeywordTypeNode("number")1160 ),1161 ],1162 undefined,1163 generator.createBlock([], false)1164 );1165 assert.strictEqual(1166 getAst(1167 expression.toString({1168 members: [],1169 })1170 ),1171 getAst(`m(p1=10, p2){}`)1172 );1173 });1174 mocha.it("Parameter with spread", function () {1175 const parameter = generator.createParameter(1176 [],1177 [],1178 "...",1179 generator.createIdentifier("a"),1180 undefined,1181 generator.createKeywordTypeNode("object[]"),1182 undefined1183 );1184 assert.equal(parameter.toString(), "...a");1185 assert.equal(parameter.typeDeclaration(), "a:any");1186 });1187 mocha.it("GetAccessor", function () {1188 const expression = generator.createGetAccessor(1189 [createDecorator("SomeDecorator")],1190 ["public"],1191 generator.createIdentifier("m"),1192 [],1193 undefined,1194 generator.createBlock([], false)1195 );1196 assert.strictEqual(1197 getAst(1198 expression.toString({1199 members: [],1200 })1201 ),1202 getAst("m(){}")1203 );1204 assert.strictEqual(expression.getter(), "m");1205 assert.strictEqual(expression.getter("this"), "this.m");1206 });1207 });1208 mocha.describe("Template", function () {1209 mocha.describe("View Function", function () {1210 const viewFunctionBlock = generator.createBlock(1211 [1212 generator.createReturn(1213 generator.createJsxSelfClosingElement(1214 generator.createIdentifier("div"),1215 [],1216 []1217 )1218 ),1219 ],1220 false1221 );1222 mocha.it(1223 "Function that returns jsx converts to empty string",1224 function () {1225 const expression = generator.createFunctionDeclaration(1226 undefined,1227 undefined,1228 "",1229 generator.createIdentifier("view"),1230 undefined,1231 [],1232 undefined,1233 viewFunctionBlock1234 );1235 assert.strictEqual(expression.toString(), "");1236 }1237 );1238 mocha.it(1239 "ArrowFunction that returns jsx converts to empty string",1240 function () {1241 const expression = generator.createArrowFunction(1242 undefined,1243 undefined,1244 [],1245 undefined,1246 generator.SyntaxKind.EqualsGreaterThanToken,1247 viewFunctionBlock1248 );1249 assert.strictEqual(expression.toString(), "");1250 }1251 );1252 mocha.it("skip jsx function from variable declaration", function () {1253 const functionDeclaration = generator.createFunctionExpression(1254 [],1255 "",1256 undefined,1257 [],1258 [],1259 undefined,1260 viewFunctionBlock1261 );1262 const expression = generator.createVariableStatement(1263 [generator.SyntaxKind.ExportKeyword],1264 generator.createVariableDeclarationList(1265 [1266 generator.createVariableDeclaration(1267 generator.createIdentifier("viewFunction"),1268 undefined,1269 functionDeclaration1270 ),1271 ],1272 generator.SyntaxKind.ConstKeyword1273 )1274 );1275 assert.strictEqual(expression.toString(), "");1276 });1277 mocha.it(1278 "Can use jsx variable twice. Self-closing element should be cloned correctly",1279 function () {1280 const block = generator.createBlock(1281 [1282 generator.createVariableStatement(1283 [],1284 generator.createVariableDeclarationList(1285 [1286 generator.createVariableDeclaration(1287 generator.createIdentifier("v"),1288 undefined,1289 generator.createJsxSelfClosingElement(1290 generator.createIdentifier("span")1291 )1292 ),1293 ],1294 generator.SyntaxKind.ConstKeyword1295 )1296 ),1297 generator.createReturn(1298 generator.createJsxElement(1299 generator.createJsxOpeningElement(1300 generator.createIdentifier("div"),1301 [],1302 []1303 ),1304 [1305 generator.createJsxExpression(1306 undefined,1307 generator.createBinary(1308 generator.createIdentifier("c1"),1309 generator.SyntaxKind.AmpersandAmpersandToken,1310 generator.createIdentifier("v")1311 )1312 ),1313 generator.createJsxExpression(1314 undefined,1315 generator.createBinary(1316 generator.createIdentifier("c2"),1317 generator.SyntaxKind.AmpersandAmpersandToken,1318 generator.createIdentifier("v")1319 )1320 ),1321 ],1322 generator.createJsxClosingElement(1323 generator.createIdentifier("div")1324 )1325 )1326 ),1327 ],1328 false1329 );1330 const expression = generator.createFunctionDeclaration(1331 [],1332 [],1333 "",1334 generator.createIdentifier("View"),1335 [],1336 [],1337 undefined,1338 block1339 );1340 assert.strictEqual(expression.toString(), "");1341 assert.strictEqual(1342 removeSpaces(1343 expression.getTemplate({1344 members: [],1345 }) as string1346 ),1347 removeSpaces(`<div >1348 <span v-if="c1"/>1349 <span v-if="c2"/>1350 </div>`)1351 );1352 }1353 );1354 mocha.it(1355 "Can use jsx variable twice. jsx element should be cloned correctly",1356 function () {1357 const block = generator.createBlock(1358 [1359 generator.createVariableStatement(1360 [],1361 generator.createVariableDeclarationList(1362 [1363 generator.createVariableDeclaration(1364 generator.createIdentifier("v"),1365 undefined,1366 generator.createJsxElement(1367 generator.createJsxOpeningElement(1368 generator.createIdentifier("span"),1369 undefined,1370 []1371 ),1372 [],1373 generator.createJsxClosingElement(1374 generator.createIdentifier("span")1375 )1376 )1377 ),1378 ],1379 generator.SyntaxKind.ConstKeyword1380 )1381 ),1382 generator.createReturn(1383 generator.createJsxElement(1384 generator.createJsxOpeningElement(1385 generator.createIdentifier("div"),1386 [],1387 []1388 ),1389 [1390 generator.createJsxExpression(1391 undefined,1392 generator.createBinary(1393 generator.createIdentifier("c1"),1394 generator.SyntaxKind.AmpersandAmpersandToken,1395 generator.createIdentifier("v")1396 )1397 ),1398 generator.createJsxExpression(1399 undefined,1400 generator.createBinary(1401 generator.createIdentifier("c2"),1402 generator.SyntaxKind.AmpersandAmpersandToken,1403 generator.createIdentifier("v")1404 )1405 ),1406 ],1407 generator.createJsxClosingElement(1408 generator.createIdentifier("div")1409 )1410 )1411 ),1412 ],1413 false1414 );1415 const expression = generator.createFunctionDeclaration(1416 [],1417 [],1418 "",1419 generator.createIdentifier("View"),1420 [],1421 [],1422 undefined,1423 block1424 );1425 assert.strictEqual(expression.toString(), "");1426 assert.strictEqual(1427 removeSpaces(1428 expression.getTemplate({1429 members: [],1430 }) as string1431 ),1432 removeSpaces(`<div >1433 <span v-if="c1"></span>1434 <span v-if="c2"></span>1435 </div>`)1436 );1437 }1438 );1439 mocha.it("Wrap single template in fragment. Function", function () {1440 const block = generator.createBlock(1441 [1442 generator.createReturn(1443 generator.createJsxSelfClosingElement(1444 generator.createPropertyAccess(1445 generator.createPropertyAccess(1446 generator.createIdentifier("model"),1447 generator.createIdentifier("props")1448 ),1449 generator.createIdentifier("contentTemplate")1450 )1451 )1452 ),1453 ],1454 false1455 );1456 const expression = generator.createFunctionDeclaration(1457 [],1458 [],1459 "",1460 generator.createIdentifier("View"),1461 [],1462 [1463 generator.createParameter(1464 [],1465 [],1466 undefined,1467 generator.createIdentifier("model")1468 ),1469 ],1470 undefined,1471 block1472 );1473 const templateProperty = generator.createProperty(1474 [createDecorator(Decorators.Template)],1475 undefined,1476 generator.createIdentifier("contentTemplate")1477 );1478 assert.strictEqual(expression.toString(), "");1479 assert.strictEqual(1480 removeSpaces(1481 expression.getTemplate({1482 members: [templateProperty],1483 }) as string1484 ),1485 removeSpaces(1486 `<div style="display:contents"><slot name="contentTemplate"></slot></div>`1487 )1488 );1489 });1490 mocha.it("Wrap single template in fragment. ArrowFunction", function () {1491 const block = generator.createBlock(1492 [1493 generator.createReturn(1494 generator.createJsxSelfClosingElement(1495 generator.createPropertyAccess(1496 generator.createPropertyAccess(1497 generator.createIdentifier("model"),1498 generator.createIdentifier("props")1499 ),1500 generator.createIdentifier("contentTemplate")1501 )1502 )1503 ),1504 ],1505 false1506 );1507 const expression = generator.createArrowFunction(1508 [],1509 [],1510 [1511 generator.createParameter(1512 [],1513 [],1514 undefined,1515 generator.createIdentifier("model")1516 ),1517 ],1518 undefined,1519 generator.SyntaxKind.EqualsGreaterThanToken,1520 block1521 );1522 const templateProperty = generator.createProperty(1523 [createDecorator(Decorators.Template)],1524 undefined,1525 generator.createIdentifier("contentTemplate")1526 );1527 assert.strictEqual(expression.toString(), "");1528 assert.strictEqual(1529 removeSpaces(1530 expression.getTemplate({1531 members: [templateProperty],1532 }) as string1533 ),1534 removeSpaces(1535 `<div style="display:contents"><slot name="contentTemplate"></slot></div>`1536 )1537 );1538 });1539 });1540 });1541 mocha.describe("Component Input", function () {1542 mocha.it("Component Binding should be an object", function () {1543 const expression = generator.createClassDeclaration(1544 [createDecorator("ComponentBindings")],1545 ["export"],1546 generator.createIdentifier("Props"),1547 [],1548 [],1549 [1550 generator.createProperty(1551 [createDecorator("OneWay")],1552 [],1553 generator.createIdentifier("p"),1554 undefined,1555 generator.createKeywordTypeNode("string"),1556 undefined1557 ),1558 generator.createProperty(1559 [createDecorator("OneWay")],1560 [],1561 generator.createIdentifier("p1"),1562 undefined,1563 generator.createKeywordTypeNode("number"),1564 undefined1565 ),1566 ]1567 );1568 assert.strictEqual(1569 getAst(expression.toString()),1570 getAst(`export const Props = {1571 p: {type: String},1572 p1: {type: Number}1573 }`)1574 );1575 });1576 mocha.it("ComponentBindings with heritage clauses", function () {1577 const expression = generator.createClassDeclaration(1578 [createDecorator("ComponentBindings")],1579 ["export"],1580 generator.createIdentifier("Props"),1581 [],1582 [1583 generator.createHeritageClause(generator.SyntaxKind.ExtendsKeyword, [1584 generator.createExpressionWithTypeArguments(1585 undefined,1586 generator.createIdentifier("Base")1587 ),1588 ]),1589 ],1590 [1591 generator.createProperty(1592 [createDecorator("OneWay")],1593 [],1594 generator.createIdentifier("p"),1595 undefined,1596 generator.createKeywordTypeNode("string"),1597 undefined1598 ),1599 ]1600 );1601 assert.strictEqual(1602 getAst(expression.toString()),1603 getAst(`export const Props = {1604 ...Base,1605 p: {type: String}1606 }`)1607 );1608 });1609 });1610 mocha.describe("Component", function () {1611 mocha.describe("Compile Effects", function () {1612 this.beforeEach(function () {1613 this.effect = generator.createMethod(1614 [createDecorator("Effect")],1615 [],1616 undefined,1617 generator.createIdentifier("e"),1618 undefined,1619 undefined,1620 [],1621 undefined,1622 generator.createBlock([], true)1623 );1624 });1625 mocha.it("should add watch for properties in dependency", function () {1626 this.effect.body = generator.createBlock(1627 [1628 generator.createPropertyAccess(1629 generator.createThis(),1630 generator.createIdentifier("p")1631 ),1632 generator.createPropertyAccess(1633 generator.createThis(),1634 generator.createIdentifier("p2")1635 ),1636 ],1637 false1638 );1639 const component = createComponent(1640 ["p", "p1", "p2"]1641 .map((name) =>1642 generator.createProperty(1643 [createDecorator("OneWay")],1644 undefined,1645 generator.createIdentifier(name),1646 undefined,1647 undefined,1648 undefined1649 )1650 )1651 .concat(this.effect)1652 ) as VueComponent;1653 const watch = component.generateWatch([]);1654 assert.strictEqual(1655 getAst(watch),1656 getAst(`watch: {1657 p: ["__schedule_e"],1658 p2: ["__schedule_e"]1659 }`)1660 );1661 });1662 mocha.it("should watch all props if props in dependency", function () {1663 this.effect.body = generator.createBlock(1664 [1665 generator.createPropertyAccess(1666 generator.createThis(),1667 generator.createIdentifier("props")1668 ),1669 ],1670 false1671 );1672 const component = createComponent(1673 ["p", "p1", "p2"]1674 .map((name) =>1675 generator.createProperty(1676 [createDecorator("OneWay")],1677 undefined,1678 generator.createIdentifier(name),1679 undefined,1680 undefined,1681 undefined1682 )1683 )1684 .concat(this.effect)1685 ) as VueComponent;1686 const watch = component.generateWatch([]);1687 assert.strictEqual(1688 getAst(watch),1689 getAst(`watch: {1690 p: ["__schedule_e"],1691 p1: ["__schedule_e"],1692 p2: ["__schedule_e"]1693 }`)1694 );1695 });1696 mocha.it(1697 "should not generate watch if there is not any dependency",1698 function () {1699 const component = createComponent(1700 ["p", "p1"]1701 .map((name) =>1702 generator.createProperty(1703 [createDecorator("OneWay")],1704 undefined,1705 generator.createIdentifier(name),1706 undefined,1707 undefined,1708 undefined1709 )1710 )1711 .concat(this.effect)1712 ) as VueComponent;1713 const methods: string[] = [];1714 const watch = component.generateWatch(methods);1715 assert.strictEqual(watch, "");1716 assert.deepEqual(methods, []);1717 }1718 );1719 mocha.it("two effect have same dependency", function () {1720 const effect = generator.createMethod(1721 [createDecorator("Effect")],1722 [],1723 undefined,1724 generator.createIdentifier("e1"),1725 undefined,1726 undefined,1727 [],1728 undefined,1729 generator.createBlock(1730 [1731 generator.createPropertyAccess(1732 generator.createThis(),1733 generator.createIdentifier("p")1734 ),1735 ],1736 true1737 )1738 );1739 this.effect.body = generator.createBlock(1740 [1741 generator.createPropertyAccess(1742 generator.createThis(),1743 generator.createIdentifier("p")1744 ),1745 generator.createPropertyAccess(1746 generator.createThis(),1747 generator.createIdentifier("p2")1748 ),1749 ],1750 false1751 );1752 const component = createComponent(1753 ["p", "p1", "p2"]1754 .map((name) =>1755 generator.createProperty(1756 [createDecorator("OneWay")],1757 undefined,1758 generator.createIdentifier(name),1759 undefined,1760 undefined,1761 undefined1762 )1763 )1764 .concat([this.effect, effect])1765 ) as VueComponent;1766 const methods: string[] = [];1767 const watch = component.generateWatch(methods);1768 assert.strictEqual(1769 getAst(watch),1770 getAst(`watch: {1771 p: ["__schedule_e", "__schedule_e1"],1772 p2: ["__schedule_e"]1773 }`)1774 );1775 assert.strictEqual(1776 getAst(`{1777 ${methods.join(",\n")}1778 }`),1779 getAst(`{1780 __schedule_e() {1781 this.__scheduleEffect(0, "__e");1782 },1783 __schedule_e1() {1784 this.__scheduleEffect(1, "__e1");1785 },1786 __scheduleEffect(index, name){1787 if(!this.__scheduleEffects[index]){1788 this.__scheduleEffects[index]=()=>{1789 this.__destroyEffects[index]&&this.__destroyEffects[index]();1790 this.__destroyEffects[index]=this[name]();1791 this.__scheduleEffects[index] = null;1792 }1793 this.$nextTick(()=>this.__scheduleEffects[index]&&this.__scheduleEffects[index]());1794 }1795 }1796 }`)1797 );1798 });1799 });1800 mocha.describe("template", function () {1801 this.beforeEach(function () {1802 generator.setContext({1803 path: __filename,1804 dirname: __dirname,1805 });1806 });1807 this.afterEach(function () {1808 generator.setContext(null);1809 });1810 mocha.it("pass isSvg to template options", function () {1811 generator.createFunctionDeclaration(1812 [],1813 [],1814 "",1815 generator.createIdentifier("viewFunction"),1816 undefined,1817 [],1818 undefined,1819 generator.createBlock(1820 [1821 generator.createReturn(1822 generator.createJsxElement(1823 generator.createJsxOpeningElement(1824 generator.createIdentifier("Fragment")1825 ),1826 [],1827 generator.createJsxClosingElement(1828 generator.createIdentifier("Fragment")1829 )1830 )1831 ),1832 ],1833 false1834 )1835 );1836 const component = createComponent([], {1837 view: generator.createIdentifier("viewFunction"),1838 isSVG: generator.createTrue(),1839 }) as VueComponent;1840 component.toString();1841 assert.strictEqual(component.template, "<g ></g>");1842 });1843 });1844 });1845 mocha.describe("Template Generation", function () {1846 mocha.describe("Elements", function () {1847 mocha.it("Self-closing element", function () {1848 const expression = generator.createJsxSelfClosingElement(1849 generator.createIdentifier("span")1850 );1851 assert.strictEqual(expression.toString(), "<span />");1852 });1853 mocha.it("element", function () {1854 const expression = generator.createJsxElement(1855 generator.createJsxOpeningElement(generator.createIdentifier("div")),1856 [],1857 generator.createJsxClosingElement(generator.createIdentifier("div"))1858 );1859 assert.strictEqual(expression.toString(), "<div ></div>");1860 });1861 mocha.it(1862 "Element with two children: should not be any whitespace symbols between elements",1863 function () {1864 const expression = generator.createJsxElement(1865 generator.createJsxOpeningElement(1866 generator.createIdentifier("div")1867 ),1868 [1869 generator.createJsxSelfClosingElement(1870 generator.createIdentifier("span")1871 ),1872 generator.createJsxSelfClosingElement(1873 generator.createIdentifier("span")1874 ),1875 ],1876 generator.createJsxClosingElement(generator.createIdentifier("div"))1877 );1878 assert.strictEqual(1879 expression.toString(),1880 "<div ><span /><span /></div>"1881 );1882 }1883 );1884 mocha.it("element with attributes", function () {1885 const expression = generator.createJsxElement(1886 generator.createJsxOpeningElement(1887 generator.createIdentifier("div"),1888 [],1889 [1890 generator.createJsxAttribute(1891 generator.createIdentifier("a"),1892 generator.createNumericLiteral("10")1893 ),1894 generator.createJsxAttribute(1895 generator.createIdentifier("b"),1896 generator.createStringLiteral("word")1897 ),1898 ]1899 ),1900 [],1901 generator.createJsxClosingElement(generator.createIdentifier("div"))1902 );1903 assert.strictEqual(1904 removeSpaces(expression.toString()),1905 removeSpaces(`<div :a="10" b="word"></div>`)1906 );1907 });1908 mocha.it("JsxAttribute without initializer", function () {1909 const expression = generator.createJsxAttribute(1910 generator.createIdentifier("a"),1911 undefined1912 );1913 assert.strictEqual(1914 removeSpaces(expression.toString()),1915 removeSpaces(`:a="true"`)1916 );1917 });1918 mocha.it(`JsxSpreadAttribute replace " -> '`, function () {1919 const expression = generator.createJsxSpreadAttribute(1920 generator.createObjectLiteral(1921 [1922 generator.createPropertyAssignment(1923 generator.createIdentifier("a"),1924 generator.createStringLiteral("str")1925 ),1926 ],1927 false1928 )1929 );1930 assert.strictEqual(expression.toString(), `v-bind="{a:'str'}"`);1931 });1932 mocha.it("render element from variable", function () {1933 const variable = generator.createJsxElement(1934 generator.createJsxOpeningElement(1935 generator.createIdentifier("span"),1936 undefined,1937 []1938 ),1939 [],1940 generator.createJsxClosingElement(generator.createIdentifier("span"))1941 );1942 const expression = generator.createJsxElement(1943 generator.createJsxOpeningElement(1944 generator.createIdentifier("div"),1945 undefined,1946 []1947 ),1948 [1949 generator.createJsxExpression(1950 undefined,1951 generator.createIdentifier("var")1952 ),1953 ],1954 generator.createJsxClosingElement(generator.createIdentifier("div"))1955 );1956 assert.strictEqual(1957 expression.toString({1958 members: [],1959 variables: {1960 var: variable,1961 },1962 }),1963 `<div ><span ></span></div>`1964 );1965 });1966 mocha.describe("Attributes", function () {1967 mocha.it("title attribute", function () {1968 const expression = generator.createJsxAttribute(1969 generator.createIdentifier("title"),1970 generator.createNumericLiteral("10")1971 );1972 assert.strictEqual(expression.toString(), `:title="10"`);1973 });1974 mocha.it("style -> v-bind:style", function () {1975 const expression = generator.createJsxAttribute(1976 generator.createIdentifier("style"),1977 generator.createJsxExpression(1978 undefined,1979 generator.createIdentifier("value")1980 )1981 );1982 assert.strictEqual(1983 expression.toString(),1984 `v-bind:style="__processStyle(value)"`1985 );1986 });1987 mocha.it("className -> v-bind:class", function () {1988 const expression = generator.createJsxAttribute(1989 generator.createIdentifier("className"),1990 generator.createJsxExpression(1991 undefined,1992 generator.createIdentifier("value")1993 )1994 );1995 assert.strictEqual(expression.toString(), `v-bind:class="value"`);1996 });1997 mocha.it("className -> class", function () {1998 const expression = generator.createJsxAttribute(1999 generator.createIdentifier("className"),2000 generator.createJsxExpression(2001 undefined,2002 generator.createStringLiteral("value")2003 )2004 );2005 assert.strictEqual(expression.toString(), `class="value"`);2006 });2007 mocha.it("Parse style with options should fill hasClass", function () {2008 const expression = generator.createJsxAttribute(2009 generator.createIdentifier("style"),2010 generator.createJsxExpression(2011 undefined,2012 generator.createIdentifier("value")2013 )2014 );2015 const options: toStringOptions = {2016 members: [],2017 };2018 assert.strictEqual(2019 expression.toString(options),2020 `v-bind:style="__processStyle(value)"`2021 );2022 assert.strictEqual(options.hasStyle, true);2023 });2024 mocha.it("camelCase->camel-case for kebab attributes", function () {2025 const attribute = generator.createJsxAttribute(2026 generator.createIdentifier("strokeWidth"),2027 generator.createJsxExpression(2028 undefined,2029 generator.createNumericLiteral("10")2030 )2031 );2032 assert.strictEqual(attribute.toString(), `:stroke-width="10"`);2033 });2034 mocha.it(2035 "camelCase->camelCase for not-kebab-case attribute",2036 function () {2037 const expression = generator.createJsxAttribute(2038 generator.createIdentifier("viewBox"),2039 generator.createJsxExpression(2040 undefined,2041 generator.createIdentifier("value")2042 )2043 );2044 assert.strictEqual(2045 expression.toString({2046 members: [],2047 isSVG: true,2048 }),2049 `:viewBox="value"`2050 );2051 }2052 );2053 });2054 mocha.describe("Fragment", function () {2055 mocha.it("Fragment -> div", function () {2056 const element = generator.createJsxElement(2057 generator.createJsxOpeningElement(2058 generator.createIdentifier("Fragment"),2059 undefined,2060 []2061 ),2062 [],2063 generator.createJsxClosingElement(2064 generator.createIdentifier("Fragment")2065 )2066 );2067 assert.strictEqual(2068 element.toString(),2069 `<div style="display: contents" ></div>`2070 );2071 });2072 mocha.it("svg: Fragment -> g", function () {2073 const element = generator.createJsxElement(2074 generator.createJsxOpeningElement(2075 generator.createIdentifier("Fragment"),2076 undefined,2077 []2078 ),2079 [],2080 generator.createJsxClosingElement(2081 generator.createIdentifier("Fragment")2082 )2083 );2084 assert.strictEqual(2085 element.toString({2086 members: [],2087 isSVG: true,2088 }),2089 `<g ></g>`2090 );2091 });2092 });2093 });2094 mocha.describe("Conditional Rendering", function () {2095 mocha.it(2096 "notJsxExpr && <element></element> -> <element v-if='notJsxExpr'></element>",2097 function () {2098 const expression = generator.createJsxElement(2099 generator.createJsxOpeningElement(2100 generator.createIdentifier("div"),2101 undefined,2102 []2103 ),2104 [2105 generator.createJsxExpression(2106 undefined,2107 generator.createBinary(2108 generator.createPropertyAccess(2109 generator.createIdentifier("viewModel"),2110 generator.createIdentifier("input")2111 ),2112 generator.createToken(2113 generator.SyntaxKind.AmpersandAmpersandToken2114 ),2115 generator.createJsxElement(2116 generator.createJsxOpeningElement(2117 generator.createIdentifier("input"),2118 undefined,2119 []2120 ),2121 [],2122 generator.createJsxClosingElement(2123 generator.createIdentifier("input")2124 )2125 )2126 )2127 ),2128 ],2129 generator.createJsxClosingElement(generator.createIdentifier("div"))2130 );2131 assert.strictEqual(2132 expression.children[0].toString(),2133 `<input v-if="viewModel.input"></input>`2134 );2135 }2136 );2137 mocha.it(2138 "notJsxExpr && <element/> -> <element v-if='notJsxExpr'>",2139 function () {2140 const expression = generator.createJsxElement(2141 generator.createJsxOpeningElement(2142 generator.createIdentifier("div"),2143 undefined,2144 []2145 ),2146 [2147 generator.createJsxExpression(2148 undefined,2149 generator.createBinary(2150 generator.createPropertyAccess(2151 generator.createIdentifier("viewModel"),2152 generator.createIdentifier("input")2153 ),2154 generator.createToken(2155 generator.SyntaxKind.AmpersandAmpersandToken2156 ),2157 generator.createJsxSelfClosingElement(2158 generator.createIdentifier("input"),2159 undefined,2160 []2161 )2162 )2163 ),2164 ],2165 generator.createJsxClosingElement(generator.createIdentifier("div"))2166 );2167 assert.strictEqual(2168 expression.children[0].toString(),2169 `<input v-if="viewModel.input"/>`2170 );2171 }2172 );2173 mocha.it(2174 "condition?then:else - <div v-if='condition'> <div v-else>",2175 function () {2176 const attribute = generator.createJsxAttribute(2177 generator.createIdentifier("a"),2178 generator.createPropertyAccess(2179 generator.createIdentifier("viewModel"),2180 generator.createIdentifier("value")2181 )2182 );2183 const property = generator.createGetAccessor(2184 [],2185 [],2186 generator.createIdentifier("value"),2187 [],2188 undefined,2189 undefined2190 );2191 property.prefix = "_";2192 const expression = generator.createJsxElement(2193 generator.createJsxOpeningElement(2194 generator.createIdentifier("div"),2195 undefined,2196 []2197 ),2198 [2199 generator.createJsxExpression(2200 undefined,2201 generator.createConditional(2202 generator.createIdentifier("condition"),2203 generator.createJsxSelfClosingElement(2204 generator.createIdentifier("input"),2205 [],2206 [attribute]2207 ),2208 generator.createJsxSelfClosingElement(2209 generator.createIdentifier("input"),2210 [],2211 [attribute]2212 )2213 )2214 ),2215 ],2216 generator.createJsxClosingElement(generator.createIdentifier("div"))2217 );2218 assert.strictEqual(2219 removeSpaces(2220 expression.children[0].toString({2221 componentContext: "viewModel",2222 newComponentContext: "",2223 members: [property],2224 })2225 ),2226 removeSpaces(2227 `<input :a="_value" v-if="condition"/>\n<input :a="_value" v-else/>`2228 )2229 );2230 }2231 );2232 mocha.it(2233 "non jsx conditional - condition?then:else - {{then}} {{else}}'",2234 function () {2235 const thenStatement = generator.createPropertyAccess(2236 generator.createIdentifier("viewModel"),2237 generator.createIdentifier("value")2238 );2239 const elseStatement = generator.createPrefix(2240 generator.SyntaxKind.ExclamationToken,2241 generator.createPropertyAccess(2242 generator.createIdentifier("viewModel"),2243 generator.createIdentifier("value")2244 )2245 );2246 const property = generator.createGetAccessor(2247 [],2248 [],2249 generator.createIdentifier("value"),2250 [],2251 undefined,2252 undefined2253 );2254 property.prefix = "_";2255 const expression = generator.createJsxElement(2256 generator.createJsxOpeningElement(2257 generator.createIdentifier("div"),2258 undefined,2259 []2260 ),2261 [2262 generator.createJsxExpression(2263 undefined,2264 generator.createConditional(2265 generator.createIdentifier("condition"),2266 thenStatement,2267 elseStatement2268 )2269 ),2270 ],2271 generator.createJsxClosingElement(generator.createIdentifier("div"))2272 );2273 assert.strictEqual(2274 removeSpaces(2275 expression.children[0].toString({2276 componentContext: "viewModel",2277 newComponentContext: "",2278 members: [property],2279 })2280 ),2281 removeSpaces(2282 `<template v-if="condition">{{_value}}</template><template v-else>{{!_value}}</template>`2283 )2284 );2285 }2286 );2287 mocha.it(2288 "condition?<element>:expr - <element><template>{expr}</template>'",2289 function () {2290 const thenStatement = generator.createJsxSelfClosingElement(2291 generator.createIdentifier("input"),2292 [],2293 []2294 );2295 const elseStatement = generator.createPropertyAccess(2296 generator.createPropertyAccess(2297 generator.createIdentifier("model"),2298 generator.createIdentifier("props")2299 ),2300 generator.createIdentifier("value")2301 );2302 const property = generator.createProperty(2303 [createDecorator("Template")],2304 [],2305 generator.createIdentifier("template")2306 );2307 generator.createJsxExpression(2308 undefined,2309 generator.createConditional(2310 generator.createIdentifier("condition"),2311 thenStatement,2312 elseStatement2313 )2314 );2315 const expression = generator.createJsxElement(2316 generator.createJsxOpeningElement(2317 generator.createIdentifier("div"),2318 undefined,2319 []2320 ),2321 [2322 generator.createJsxExpression(2323 undefined,2324 generator.createConditional(2325 generator.createIdentifier("condition"),2326 generator.createJsxSelfClosingElement(2327 generator.createPropertyAccess(2328 generator.createPropertyAccess(2329 generator.createIdentifier("model"),2330 generator.createIdentifier("props")2331 ),2332 generator.createIdentifier("template")2333 ),2334 undefined,2335 [2336 generator.createJsxAttribute(2337 generator.createIdentifier("text"),2338 generator.createJsxExpression(2339 undefined,2340 generator.createPropertyAccess(2341 generator.createPropertyAccess(2342 generator.createIdentifier("model"),2343 generator.createIdentifier("props")2344 ),2345 generator.createIdentifier("text")2346 )2347 )2348 ),2349 ]2350 ),2351 generator.createIdentifier("text")2352 )2353 ),2354 ],2355 generator.createJsxClosingElement(generator.createIdentifier("div"))2356 );2357 assert.strictEqual(2358 removeSpaces(2359 expression.children[0].toString({2360 componentContext: "model",2361 newComponentContext: "",2362 members: [property],2363 })2364 ),2365 removeSpaces(`2366 <slot name="template" v-bind:text="props.text" v-if="condition"></slot>2367 <template v-else>{{text}}</template>2368 `)2369 );2370 }2371 );2372 mocha.it("Condition with identifer that point to element", function () {2373 const identifier = generator.createIdentifier("var");2374 const expression = generator.createJsxElement(2375 generator.createJsxOpeningElement(2376 generator.createIdentifier("div"),2377 undefined,2378 []2379 ),2380 [2381 generator.createJsxExpression(2382 undefined,2383 generator.createConditional(2384 generator.createIdentifier("condition"),2385 generator.createJsxSelfClosingElement(2386 generator.createIdentifier("input"),2387 [],2388 []2389 ),2390 identifier2391 )2392 ),2393 ],2394 generator.createJsxClosingElement(generator.createIdentifier("div"))2395 );2396 assert.strictEqual(2397 removeSpaces(2398 expression.children[0].toString({2399 componentContext: "model",2400 newComponentContext: "",2401 members: [],2402 variables: {2403 [identifier.toString()]: generator.createJsxSelfClosingElement(2404 generator.createIdentifier("span")2405 ),2406 },2407 })2408 ),2409 removeSpaces(`<input v-if="condition"/><span v-else/>`)2410 );2411 });2412 mocha.describe("Slots with conditional rendering", function () {2413 this.beforeEach(function () {2414 this.slotProperty = generator.createProperty(2415 [createDecorator("Slot")],2416 [],2417 generator.createIdentifier("children"),2418 generator.SyntaxKind.QuestionToken,2419 undefined,2420 undefined2421 );2422 this.slotExpression = generator.createPropertyAccess(2423 generator.createPropertyAccess(2424 generator.createIdentifier("viewModel"),2425 generator.createIdentifier("props")2426 ),2427 generator.createIdentifier("children")2428 );2429 this.toStringOptions = {2430 members: [this.slotProperty],2431 componentContext: "viewModel",2432 newComponentContext: "",2433 } as toStringOptions;2434 });2435 function createElement(children: JsxExpression[]) {2436 return generator.createJsxElement(2437 generator.createJsxOpeningElement(2438 generator.createIdentifier("div"),2439 undefined,2440 []2441 ),2442 children,2443 generator.createJsxClosingElement(generator.createIdentifier("div"))2444 );2445 }2446 mocha.it("slot? slot: alternative content", function () {2447 const element = createElement([2448 generator.createJsxExpression(2449 undefined,2450 generator.createConditional(2451 this.slotExpression,2452 this.slotExpression,2453 generator.createIdentifier("alternative")2454 )2455 ),2456 ]);2457 assert.strictEqual(2458 removeSpaces(element.children[0].toString(this.toStringOptions)),2459 removeSpaces(`2460 <template v-if="$slots.default"><slot></slot></template>2461 <template v-else>{{alternative}}</template>2462 `)2463 );2464 });2465 mocha.it("render slot if template is not exist", function () {2466 const element = createElement([2467 generator.createJsxExpression(2468 undefined,2469 generator.createBinary(2470 generator.createPrefix(2471 generator.SyntaxKind.ExclamationToken,2472 generator.createIdentifier("template")2473 ),2474 generator.SyntaxKind.AmpersandAmpersandToken,2475 this.slotExpression2476 )2477 ),2478 ]);2479 const templateProperty = generator.createProperty(2480 [createDecorator(Decorators.Template)],2481 [],2482 generator.createIdentifier("template")2483 );2484 assert.strictEqual(2485 removeSpaces(2486 element.children[0].toString({2487 ...this.toStringOptions,2488 members: [...this.toStringOptions.members, templateProperty],2489 variables: {2490 template: generator.createPropertyAccess(2491 generator.createPropertyAccess(2492 generator.createIdentifier("viewModel"),2493 generator.createIdentifier("props")2494 ),2495 generator.createIdentifier("template")2496 ),2497 },2498 })2499 ),2500 removeSpaces(`2501 <template v-if="!$scopedSlots.template"><slot></slot></template>2502 `)2503 );2504 });2505 });2506 });2507 mocha.describe("Parse Map function", function () {2508 mocha.it(".map((item)=><div>) -> v-for", function () {2509 const expression = generator.createJsxElement(2510 generator.createJsxOpeningElement(2511 generator.createIdentifier("div"),2512 undefined,2513 []2514 ),2515 [2516 generator.createJsxExpression(2517 undefined,2518 generator.createCall(2519 generator.createPropertyAccess(2520 generator.createPropertyAccess(2521 generator.createIdentifier("viewModel"),2522 generator.createIdentifier("items")2523 ),2524 generator.createIdentifier("map")2525 ),2526 undefined,2527 [2528 generator.createArrowFunction(2529 undefined,2530 undefined,2531 [2532 generator.createParameter(2533 undefined,2534 undefined,2535 undefined,2536 generator.createIdentifier("items"),2537 undefined,2538 undefined,2539 undefined2540 ),2541 ],2542 undefined,2543 generator.createToken(2544 generator.SyntaxKind.EqualsGreaterThanToken2545 ),2546 generator.createJsxElement(2547 generator.createJsxOpeningElement(2548 generator.createIdentifier("div"),2549 undefined,2550 generator.createJsxAttributes([])2551 ),2552 [],2553 generator.createJsxClosingElement(2554 generator.createIdentifier("div")2555 )2556 )2557 ),2558 ]2559 )2560 ),2561 ],2562 generator.createJsxClosingElement(generator.createIdentifier("div"))2563 );2564 assert.strictEqual(2565 expression.children[0].toString(),2566 `<template v-for="items of viewModel.items"><div ></div></template>`2567 );2568 });2569 mocha.it(".map((item)=>item) -> *ngFor", function () {2570 const expression = generator.createJsxElement(2571 generator.createJsxOpeningElement(2572 generator.createIdentifier("div"),2573 undefined,2574 []2575 ),2576 [2577 generator.createJsxExpression(2578 undefined,2579 generator.createCall(2580 generator.createPropertyAccess(2581 generator.createPropertyAccess(2582 generator.createIdentifier("viewModel"),2583 generator.createIdentifier("items")2584 ),2585 generator.createIdentifier("map")2586 ),2587 undefined,2588 [2589 generator.createArrowFunction(2590 undefined,2591 undefined,2592 [2593 generator.createParameter(2594 undefined,2595 undefined,2596 undefined,2597 generator.createIdentifier("items"),2598 undefined,2599 undefined,2600 undefined2601 ),2602 ],2603 undefined,2604 generator.createToken(2605 generator.SyntaxKind.EqualsGreaterThanToken2606 ),2607 generator.createIdentifier("items")2608 ),2609 ]2610 )2611 ),2612 ],2613 generator.createJsxClosingElement(generator.createIdentifier("div"))2614 );2615 assert.strictEqual(2616 expression.children[0].toString(),2617 `<template v-for="items of viewModel.items">{{items}}</template>`2618 );2619 });2620 mocha.it(".map((item)=>{}) -> empty string", function () {2621 const expression = generator.createJsxElement(2622 generator.createJsxOpeningElement(2623 generator.createIdentifier("div"),2624 undefined,2625 []2626 ),2627 [2628 generator.createJsxExpression(2629 undefined,2630 generator.createCall(2631 generator.createPropertyAccess(2632 generator.createPropertyAccess(2633 generator.createIdentifier("viewModel"),2634 generator.createIdentifier("items")2635 ),2636 generator.createIdentifier("map")2637 ),2638 undefined,2639 [2640 generator.createArrowFunction(2641 undefined,2642 undefined,2643 [2644 generator.createParameter(2645 undefined,2646 undefined,2647 undefined,2648 generator.createIdentifier("items"),2649 undefined,2650 undefined,2651 undefined2652 ),2653 ],2654 undefined,2655 generator.createToken(2656 generator.SyntaxKind.EqualsGreaterThanToken2657 ),2658 generator.createBlock([], false)2659 ),2660 ]2661 )2662 ),2663 ],2664 generator.createJsxClosingElement(generator.createIdentifier("div"))2665 );2666 assert.strictEqual(expression.children[0].toString(), "");2667 });2668 mocha.it(2669 ".map((item, index)=><div>) -> v-for='(item, index) of items'",2670 function () {2671 const expression = generator.createJsxElement(2672 generator.createJsxOpeningElement(2673 generator.createIdentifier("div"),2674 undefined,2675 []2676 ),2677 [2678 generator.createJsxExpression(2679 undefined,2680 generator.createCall(2681 generator.createPropertyAccess(2682 generator.createPropertyAccess(2683 generator.createIdentifier("viewModel"),2684 generator.createIdentifier("items")2685 ),2686 generator.createIdentifier("map")2687 ),2688 undefined,2689 [2690 generator.createArrowFunction(2691 undefined,2692 undefined,2693 [2694 generator.createParameter(2695 undefined,2696 undefined,2697 undefined,2698 generator.createIdentifier("items"),2699 undefined,2700 undefined,2701 undefined2702 ),2703 generator.createParameter(2704 undefined,2705 undefined,2706 undefined,2707 generator.createIdentifier("i"),2708 undefined,2709 undefined,2710 undefined2711 ),2712 ],2713 undefined,2714 generator.createToken(2715 generator.SyntaxKind.EqualsGreaterThanToken2716 ),2717 generator.createJsxElement(2718 generator.createJsxOpeningElement(2719 generator.createIdentifier("div"),2720 undefined,2721 generator.createJsxAttributes([])2722 ),2723 [],2724 generator.createJsxClosingElement(2725 generator.createIdentifier("div")2726 )2727 )2728 ),2729 ]2730 )2731 ),2732 ],2733 generator.createJsxClosingElement(generator.createIdentifier("div"))2734 );2735 assert.strictEqual(2736 expression.children[0].toString(),2737 `<template v-for="(items,i) of viewModel.items"><div ></div></template>`2738 );2739 }2740 );2741 mocha.it("map with key attribute", function () {2742 const expression = generator.createJsxElement(2743 generator.createJsxOpeningElement(2744 generator.createIdentifier("div"),2745 undefined,2746 []2747 ),2748 [2749 generator.createJsxExpression(2750 undefined,2751 generator.createCall(2752 generator.createPropertyAccess(2753 generator.createPropertyAccess(2754 generator.createIdentifier("viewModel"),2755 generator.createIdentifier("items")2756 ),2757 generator.createIdentifier("map")2758 ),2759 undefined,2760 [2761 generator.createArrowFunction(2762 undefined,2763 undefined,2764 [2765 generator.createParameter(2766 undefined,2767 undefined,2768 undefined,2769 generator.createIdentifier("item"),2770 undefined,2771 undefined,2772 undefined2773 ),2774 ],2775 undefined,2776 generator.createToken(2777 generator.SyntaxKind.EqualsGreaterThanToken2778 ),2779 generator.createJsxElement(2780 generator.createJsxOpeningElement(2781 generator.createIdentifier("div"),2782 undefined,2783 generator.createJsxAttributes([2784 generator.createJsxAttribute(2785 generator.createIdentifier("key"),2786 generator.createPropertyAccess(2787 generator.createIdentifier("item"),2788 generator.createIdentifier("id")2789 )2790 ),2791 ])2792 ),2793 [],2794 generator.createJsxClosingElement(2795 generator.createIdentifier("div")2796 )2797 )2798 ),2799 ]2800 )2801 ),2802 ],2803 generator.createJsxClosingElement(generator.createIdentifier("div"))2804 );2805 assert.strictEqual(2806 removeSpaces(expression.children[0].toString()),2807 removeSpaces(2808 `<templatev-for="itemofviewModel.items"><div:key="item.id"></div></template>`2809 )2810 );2811 });2812 mocha.it("map inside an other map", function () {2813 const insideExpression = generator.createCall(2814 generator.createPropertyAccess(2815 generator.createIdentifier("item"),2816 generator.createIdentifier("map")2817 ),2818 undefined,2819 [2820 generator.createArrowFunction(2821 undefined,2822 undefined,2823 [2824 generator.createParameter(2825 undefined,2826 undefined,2827 undefined,2828 generator.createIdentifier("_"),2829 undefined,2830 undefined,2831 undefined2832 ),2833 generator.createParameter(2834 undefined,2835 undefined,2836 undefined,2837 generator.createIdentifier("i"),2838 undefined,2839 undefined,2840 undefined2841 ),2842 ],2843 undefined,2844 generator.createToken(2845 generator.SyntaxKind.EqualsGreaterThanToken2846 ),2847 generator.createJsxElement(2848 generator.createJsxOpeningElement(2849 generator.createIdentifier("div"),2850 undefined,2851 generator.createJsxAttributes([2852 generator.createJsxAttribute(2853 generator.createIdentifier("key"),2854 generator.createIdentifier("i")2855 ),2856 ])2857 ),2858 [],2859 generator.createJsxClosingElement(2860 generator.createIdentifier("div")2861 )2862 )2863 ),2864 ]2865 );2866 const expression = generator.createJsxElement(2867 generator.createJsxOpeningElement(2868 generator.createIdentifier("div"),2869 undefined,2870 []2871 ),2872 [2873 generator.createJsxExpression(2874 undefined,2875 generator.createCall(2876 generator.createPropertyAccess(2877 generator.createPropertyAccess(2878 generator.createIdentifier("viewModel"),2879 generator.createIdentifier("items")2880 ),2881 generator.createIdentifier("map")2882 ),2883 undefined,2884 [2885 generator.createArrowFunction(2886 undefined,2887 undefined,2888 [2889 generator.createParameter(2890 undefined,2891 undefined,2892 undefined,2893 generator.createIdentifier("item"),2894 undefined,2895 undefined,2896 undefined2897 ),2898 ],2899 undefined,2900 generator.createToken(2901 generator.SyntaxKind.EqualsGreaterThanToken2902 ),2903 generator.createJsxElement(2904 generator.createJsxOpeningElement(2905 generator.createIdentifier("div"),2906 undefined,2907 generator.createJsxAttributes([2908 generator.createJsxAttribute(2909 generator.createIdentifier("key"),2910 generator.createPropertyAccess(2911 generator.createIdentifier("item"),2912 generator.createIdentifier("id")2913 )2914 ),2915 ])2916 ),2917 [2918 generator.createJsxExpression(2919 undefined,2920 insideExpression2921 ),2922 ],2923 generator.createJsxClosingElement(2924 generator.createIdentifier("div")2925 )2926 )2927 ),2928 ]2929 )2930 ),2931 ],2932 generator.createJsxClosingElement(generator.createIdentifier("div"))2933 ).children[0] as JsxExpression;2934 assert.strictEqual(2935 removeSpaces(expression.toString()),2936 removeSpaces(2937 `<templatev-for="itemofviewModel.items">2938 <div:key="item.id">2939 <templatev-for="(_,i)ofitem">2940 <div:key="i"></div>2941 </template>2942 </div>2943 </template>`2944 )2945 );2946 });2947 mocha.it("Parse map with destruction", function () {2948 const expression = generator.createJsxElement(2949 generator.createJsxOpeningElement(2950 generator.createIdentifier("div"),2951 undefined,2952 []2953 ),2954 [2955 generator.createJsxExpression(2956 undefined,2957 generator.createCall(2958 generator.createPropertyAccess(2959 generator.createPropertyAccess(2960 generator.createIdentifier("viewModel"),2961 generator.createIdentifier("items")2962 ),2963 generator.createIdentifier("map")2964 ),2965 undefined,2966 [2967 generator.createArrowFunction(2968 undefined,2969 undefined,2970 [2971 generator.createParameter(2972 undefined,2973 undefined,2974 undefined,2975 generator.createObjectBindingPattern([2976 generator.createBindingElement(2977 undefined,2978 undefined,2979 generator.createIdentifier("p1")2980 ),2981 generator.createBindingElement(2982 undefined,2983 undefined,2984 generator.createIdentifier("p2")2985 ),2986 ]),2987 undefined,2988 undefined,2989 undefined2990 ),2991 ],2992 undefined,2993 generator.createToken(2994 generator.SyntaxKind.EqualsGreaterThanToken2995 ),2996 generator.createJsxElement(2997 generator.createJsxOpeningElement(2998 generator.createIdentifier("div"),2999 undefined,3000 generator.createJsxAttributes([])3001 ),3002 [3003 generator.createJsxExpression(3004 undefined,3005 generator.createIdentifier("p1")3006 ),3007 generator.createJsxExpression(3008 undefined,3009 generator.createIdentifier("p2")3010 ),3011 ],3012 generator.createJsxClosingElement(3013 generator.createIdentifier("div")3014 )3015 )3016 ),3017 ]3018 )3019 ),3020 ],3021 generator.createJsxClosingElement(generator.createIdentifier("div"))3022 );3023 const property = generator.createProperty(3024 [createDecorator("OneWay")],3025 undefined,3026 generator.createIdentifier("p1")3027 );3028 assert.strictEqual(3029 expression.children[0].toString({3030 members: [property],3031 componentContext: "model",3032 newComponentContext: "",3033 }),3034 `<template v-for="{p1,p2} of viewModel.items"><div >{{p1}}{{p2}}</div></template>`3035 );3036 });3037 });3038 mocha.describe("Template", function () {3039 mocha.it("<template/> -> <slot></slot>", function () {3040 const expression = generator.createJsxSelfClosingElement(3041 generator.createPropertyAccess(3042 generator.createIdentifier("viewModel"),3043 generator.createIdentifier("template")3044 ),3045 [],3046 []3047 );3048 const templateProperty = generator.createProperty(3049 [createDecorator("Template")],3050 [],3051 generator.createIdentifier("template"),3052 generator.SyntaxKind.QuestionToken,3053 undefined,3054 undefined3055 );3056 assert.strictEqual(3057 expression.toString({3058 members: [templateProperty],3059 componentContext: "viewModel",3060 newComponentContext: "",3061 }),3062 `<slot name="template" ></slot>`3063 );3064 });3065 mocha.it("Template with parameters", function () {3066 const expression = generator.createJsxSelfClosingElement(3067 generator.createPropertyAccess(3068 generator.createIdentifier("viewModel"),3069 generator.createIdentifier("template")3070 ),3071 [],3072 [3073 generator.createJsxAttribute(3074 generator.createIdentifier("p1"),3075 generator.createNumericLiteral("10")3076 ),3077 generator.createJsxAttribute(3078 generator.createIdentifier("p2"),3079 generator.createStringLiteral("11")3080 ),3081 ]3082 );3083 const templateProperty = generator.createProperty(3084 [createDecorator("Template")],3085 [],3086 generator.createIdentifier("template"),3087 generator.SyntaxKind.QuestionToken,3088 undefined,3089 undefined3090 );3091 assert.strictEqual(3092 expression.toString({3093 members: [templateProperty],3094 componentContext: "viewModel",3095 newComponentContext: "",3096 }),3097 `<slot name="template" v-bind:p1="10" v-bind:p2="'11'"></slot>`3098 );3099 });3100 mocha.it("<template></template> -> <slot></slot>", function () {3101 const expression = generator.createJsxElement(3102 generator.createJsxOpeningElement(3103 generator.createPropertyAccess(3104 generator.createIdentifier("viewModel"),3105 generator.createIdentifier("template")3106 ),3107 undefined,3108 []3109 ),3110 [],3111 generator.createJsxClosingElement(3112 generator.createPropertyAccess(3113 generator.createIdentifier("viewModel"),3114 generator.createIdentifier("template")3115 )3116 )3117 );3118 const templateProperty = generator.createProperty(3119 [createDecorator("Template")],3120 [],3121 generator.createIdentifier("template"),3122 generator.SyntaxKind.QuestionToken,3123 undefined,3124 undefined3125 );3126 assert.strictEqual(3127 expression.toString({3128 members: [templateProperty],3129 componentContext: "viewModel",3130 newComponentContext: "",3131 }),3132 `<slot name="template" ></slot>`3133 );3134 });3135 mocha.it("Template with spread attribute", function () {3136 const expression = generator.createJsxSelfClosingElement(3137 generator.createPropertyAccess(3138 generator.createIdentifier("viewModel"),3139 generator.createIdentifier("template")3140 ),3141 [],3142 [3143 generator.createJsxSpreadAttribute(3144 generator.createIdentifier("item")3145 ),3146 ]3147 );3148 const templateProperty = generator.createProperty(3149 [createDecorator("Template")],3150 [],3151 generator.createIdentifier("template"),3152 generator.SyntaxKind.QuestionToken,3153 undefined,3154 undefined3155 );3156 assert.strictEqual(3157 expression.toString({3158 members: [templateProperty],3159 componentContext: "viewModel",3160 newComponentContext: "",3161 }),3162 `<slot name="template" v-bind="item"></slot>`3163 );3164 });3165 mocha.it("Template with condition", function () {3166 const expression = generator.createJsxSelfClosingElement(3167 generator.createPropertyAccess(3168 generator.createPropertyAccess(3169 generator.createIdentifier("viewModel"),3170 generator.createIdentifier("props")3171 ),3172 generator.createIdentifier("template")3173 ),3174 [],3175 []3176 );3177 const element = generator.createJsxElement(3178 generator.createJsxOpeningElement(3179 generator.createIdentifier("div"),3180 undefined,3181 []3182 ),3183 [3184 generator.createJsxExpression(3185 undefined,3186 generator.createBinary(3187 generator.createPropertyAccess(3188 generator.createPropertyAccess(3189 generator.createIdentifier("viewModel"),3190 generator.createIdentifier("props")3191 ),3192 generator.createIdentifier("template")3193 ),3194 generator.SyntaxKind.AmpersandAmpersandToken,3195 expression3196 )3197 ),3198 ],3199 generator.createJsxClosingElement(generator.createIdentifier("div"))3200 );3201 const templateProperty = generator.createProperty(3202 [createDecorator("Template")],3203 [],3204 generator.createIdentifier("template"),3205 generator.SyntaxKind.QuestionToken,3206 undefined,3207 undefined3208 );3209 assert.strictEqual(3210 element.children[0].toString({3211 members: [templateProperty],3212 componentContext: "viewModel",3213 newComponentContext: "",3214 }),3215 `<slot name="template" v-if="$scopedSlots.template"></slot>`3216 );3217 });3218 });3219 mocha.describe("Slot", function () {3220 mocha.it("children slot is default", function () {3221 const expression = generator.createJsxElement(3222 generator.createJsxOpeningElement(3223 generator.createIdentifier("div"),3224 [],3225 []3226 ),3227 [3228 generator.createJsxExpression(3229 undefined,3230 generator.createPropertyAccess(3231 generator.createPropertyAccess(3232 generator.createIdentifier("viewModel"),3233 generator.createIdentifier("props")3234 ),3235 generator.createIdentifier("children")3236 )3237 ),3238 ],3239 generator.createJsxClosingElement(generator.createIdentifier("div"))3240 );3241 const slotProperty = generator.createProperty(3242 [createDecorator("Slot")],3243 [],3244 generator.createIdentifier("children"),3245 generator.SyntaxKind.QuestionToken,3246 undefined,3247 undefined3248 );3249 assert.strictEqual(3250 expression.toString({3251 members: [slotProperty],3252 componentContext: "viewModel",3253 newComponentContext: "",3254 }),3255 `<div ><slot></slot></div>`3256 );3257 });3258 mocha.it("named slot", function () {3259 const expression = generator.createJsxElement(3260 generator.createJsxOpeningElement(3261 generator.createIdentifier("div"),3262 [],3263 []3264 ),3265 [3266 generator.createJsxExpression(3267 undefined,3268 generator.createPropertyAccess(3269 generator.createPropertyAccess(3270 generator.createIdentifier("viewModel"),3271 generator.createIdentifier("props")3272 ),3273 generator.createIdentifier("slotName")3274 )3275 ),3276 ],3277 generator.createJsxClosingElement(generator.createIdentifier("div"))3278 );3279 const slotProperty = generator.createProperty(3280 [createDecorator("Slot")],3281 [],3282 generator.createIdentifier("slotName"),3283 generator.SyntaxKind.QuestionToken,3284 undefined,3285 undefined3286 );3287 assert.strictEqual(3288 expression.toString({3289 members: [slotProperty],3290 componentContext: "viewModel",3291 newComponentContext: "",3292 }),3293 `<div ><slot name="slotName"></slot></div>`3294 );3295 });3296 });3297 mocha.describe("Dynamic Components", function () {3298 this.beforeEach(function () {3299 generator.setContext({3300 path: __filename,3301 dirname: __dirname,3302 });3303 });3304 this.afterEach(function () {3305 generator.setContext(null);3306 });3307 const createGetter = (type?: TypeExpression) =>3308 generator.createGetAccessor(3309 [],3310 undefined,3311 generator.createIdentifier("DynamicComponent"),3312 [],3313 type,3314 generator.createBlock([], false)3315 );3316 const createProps = () =>3317 generator.createClassDeclaration(3318 [createDecorator(Decorators.ComponentBindings)],3319 [],3320 generator.createIdentifier("DynamicComponentProps"),3321 [],3322 [],3323 [3324 generator.createProperty(3325 [createDecorator(Decorators.OneWay)],3326 [],3327 generator.createIdentifier("prop")3328 ),3329 generator.createProperty(3330 [createDecorator(Decorators.Event)],3331 [],3332 generator.createIdentifier("event")3333 ),3334 ]3335 );3336 mocha.it("<DynamicComponent/> -> <component/>", function () {3337 const getter = createGetter();3338 const element = generator.createJsxSelfClosingElement(3339 generator.createPropertyAccess(3340 generator.createIdentifier("viewModel"),3341 getter._name3342 )3343 );3344 const options: toStringOptions = {3345 members: [getter],3346 componentContext: "viewModel",3347 newComponentContext: "",3348 };3349 assert.strictEqual(3350 removeSpaces(element.toString(options)),3351 removeSpaces(`<component v-bind:is="DynamicComponent"/>`)3352 );3353 });3354 mocha.it(3355 "<DynamicComponent></DynamicComponent> -> <component></component>",3356 function () {3357 const getter = createGetter();3358 const tag = generator.createPropertyAccess(3359 generator.createIdentifier("viewModel"),3360 getter._name3361 );3362 const element = generator.createJsxElement(3363 generator.createJsxOpeningElement(tag, undefined, []),3364 [],3365 generator.createJsxClosingElement(tag)3366 );3367 assert.strictEqual(3368 removeSpaces(3369 element.toString({3370 members: [getter],3371 componentContext: "viewModel",3372 newComponentContext: "",3373 })3374 ),3375 removeSpaces(`<component v-bind:is="DynamicComponent"></component>`)3376 );3377 }3378 );3379 mocha.it(3380 "<DynamicComponent></DynamicComponent> -> <component></component>",3381 function () {3382 const getter = createGetter();3383 const tag = generator.createPropertyAccess(3384 generator.createIdentifier("viewModel"),3385 getter._name3386 );3387 const element = generator.createJsxElement(3388 generator.createJsxOpeningElement(tag, undefined, []),3389 [],3390 generator.createJsxClosingElement(tag)3391 );3392 assert.strictEqual(3393 removeSpaces(3394 element.toString({3395 members: [getter],3396 componentContext: "viewModel",3397 newComponentContext: "",3398 })3399 ),3400 removeSpaces(`<component v-bind:is="DynamicComponent"></component>`)3401 );3402 }3403 );3404 mocha.it(3405 "<DynamicComponent><span/></DynamicComponent> -> <component></component>",3406 function () {3407 const getter = createGetter();3408 const tag = generator.createPropertyAccess(3409 generator.createIdentifier("viewModel"),3410 getter._name3411 );3412 const element = generator.createJsxElement(3413 generator.createJsxOpeningElement(tag, undefined, []),3414 [3415 generator.createJsxSelfClosingElement(3416 generator.createIdentifier("span")3417 ),3418 ],3419 generator.createJsxClosingElement(tag)3420 );3421 assert.strictEqual(3422 removeSpaces(3423 element.toString({3424 members: [getter],3425 componentContext: "viewModel",3426 newComponentContext: "",3427 })3428 ),3429 removeSpaces(`3430 <component v-bind:is="DynamicComponent">3431 <span/>3432 </component>3433 `)3434 );3435 }3436 );3437 mocha.it(3438 "<DynamicComponent prop={value}></DynamicComponent> -> <component :props='value'></component>",3439 function () {3440 const props = createProps();3441 const component = createComponent(props.members);3442 const jsxTemplateType = generator.createTypeReferenceNode(3443 generator.createIdentifier("JSXTemplate"),3444 [generator.createTypeReferenceNode(props._name)]3445 );3446 const componentType = generator.createTypeReferenceNode(3447 component._name3448 );3449 const typeofQuery = generator.createTypeQueryNode(component._name);3450 const types: TypeExpression[] = [3451 jsxTemplateType,3452 componentType,3453 typeofQuery,3454 ];3455 types.forEach((type, index) => {3456 const getter = createGetter(type);3457 const tag = generator.createPropertyAccess(3458 generator.createIdentifier("viewModel"),3459 getter._name3460 );3461 const element = generator.createJsxElement(3462 generator.createJsxOpeningElement(tag, undefined, [3463 generator.createJsxAttribute(3464 generator.createIdentifier("prop"),3465 generator.createIdentifier("propValue")3466 ),3467 generator.createJsxAttribute(3468 generator.createIdentifier("event"),3469 generator.createIdentifier("eventValue")3470 ),3471 ]),3472 [],3473 generator.createJsxClosingElement(tag)3474 );3475 assert.strictEqual(3476 removeSpaces(3477 element.toString({3478 members: [getter],3479 componentContext: "viewModel",3480 newComponentContext: "",3481 })3482 ),3483 removeSpaces(`3484 <component3485 v-bind:is="DynamicComponent"3486 :prop="propValue"3487 @event="eventValue"3488 ></component>3489 `),3490 index.toString()3491 );3492 });3493 }3494 );3495 mocha.it(3496 "<DynamicComponent template={()=><div/>}></DynamicComponent> -> <component><template></component>",3497 function () {3498 const component = createComponent([3499 generator.createProperty(3500 [createDecorator(Decorators.Template)],3501 [],3502 generator.createIdentifier("template")3503 ),3504 ]);3505 const getter = createGetter(3506 generator.createTypeReferenceNode(component._name)3507 );3508 const tag = generator.createPropertyAccess(3509 generator.createIdentifier("viewModel"),3510 getter._name3511 );3512 const element = generator.createJsxElement(3513 generator.createJsxOpeningElement(tag, undefined, [3514 generator.createJsxAttribute(3515 generator.createIdentifier("template"),3516 generator.createArrowFunction(3517 [],3518 undefined,3519 [],3520 undefined,3521 generator.SyntaxKind.EqualsGreaterThanToken,3522 generator.createJsxSelfClosingElement(3523 generator.createIdentifier("div")3524 )3525 )3526 ),3527 ]),3528 [],3529 generator.createJsxClosingElement(tag)3530 );3531 assert.strictEqual(3532 removeSpaces(3533 element.toString({3534 members: [getter],3535 componentContext: "viewModel",3536 newComponentContext: "",3537 })3538 ),3539 removeSpaces(`3540 <component3541 v-bind:is="DynamicComponent"3542 >3543 <template v-slot:template>3544 <div/>3545 </template>3546 </component>3547 `)3548 );3549 }3550 );3551 mocha.it(3552 "<DynamicComponent template={()=><div/>}/> -> <component><template></component>",3553 function () {3554 const component = createComponent([3555 generator.createProperty(3556 [createDecorator(Decorators.Template)],3557 [],3558 generator.createIdentifier("template")3559 ),3560 ]);3561 const getter = createGetter(3562 generator.createTypeReferenceNode(component._name)3563 );3564 const tag = generator.createPropertyAccess(3565 generator.createIdentifier("viewModel"),3566 getter._name3567 );3568 const element = generator.createJsxSelfClosingElement(3569 tag,3570 undefined,3571 [3572 generator.createJsxAttribute(3573 generator.createIdentifier("template"),3574 generator.createArrowFunction(3575 [],3576 undefined,3577 [],3578 undefined,3579 generator.SyntaxKind.EqualsGreaterThanToken,3580 generator.createJsxSelfClosingElement(3581 generator.createIdentifier("div")3582 )3583 )3584 ),3585 ]3586 );3587 assert.strictEqual(3588 removeSpaces(3589 element.toString({3590 members: [getter],3591 componentContext: "viewModel",3592 newComponentContext: "",3593 })3594 ),3595 removeSpaces(`3596 <component3597 v-bind:is="DynamicComponent"3598 >3599 <template v-slot:template>3600 <div/>3601 </template>3602 </component>3603 `)3604 );3605 }3606 );3607 mocha.it(3608 "condition && <DynamicComponent /> -> <component v-if='condition'>",3609 function () {3610 const getterName = "DynamicComponent";3611 const getter = generator.createGetAccessor(3612 [],3613 undefined,3614 generator.createIdentifier(getterName),3615 [],3616 undefined,3617 generator.createBlock([], false)3618 );3619 const element = generator.createJsxElement(3620 generator.createJsxOpeningElement(3621 generator.createIdentifier("div")3622 ),3623 [3624 generator.createJsxExpression(3625 undefined,3626 generator.createBinary(3627 generator.createIdentifier("condition"),3628 generator.SyntaxKind.AmpersandAmpersandToken,3629 generator.createJsxSelfClosingElement(3630 generator.createPropertyAccess(3631 generator.createIdentifier("viewModel"),3632 generator.createIdentifier(getterName)3633 )3634 )3635 )3636 ),3637 ],3638 generator.createJsxClosingElement(generator.createIdentifier("div"))3639 );3640 const options: toStringOptions = {3641 members: [getter],3642 componentContext: "viewModel",3643 newComponentContext: "",3644 };3645 assert.strictEqual(3646 removeSpaces(element.toString(options)),3647 removeSpaces(3648 `<div>3649 <component 3650 v-bind:is="DynamicComponent"3651 v-if="condition"3652 />3653 </div>`3654 )3655 );3656 }3657 );3658 mocha.it("map <DynamicComponent />", function () {3659 const props = createProps();3660 const jsxTemplateType = generator.createTypeReferenceNode(3661 generator.createIdentifier("JSXTemplate"),3662 [generator.createTypeReferenceNode(props._name)]3663 );3664 const literalArray = generator.createArrayTypeNode(jsxTemplateType);3665 const arrayType = generator.createTypeReferenceNode(3666 generator.createIdentifier("Array"),3667 [jsxTemplateType]3668 );3669 const types: TypeExpression[] = [literalArray, arrayType];3670 types.forEach((type) => {3671 const getter = createGetter(type);3672 const element = generator.createJsxElement(3673 generator.createJsxOpeningElement(3674 generator.createIdentifier("div")3675 ),3676 [3677 generator.createJsxExpression(3678 undefined,3679 generator.createCall(3680 generator.createPropertyAccess(3681 generator.createPropertyAccess(3682 generator.createIdentifier("viewModel"),3683 getter._name3684 ),3685 generator.createIdentifier("map")3686 ),3687 undefined,3688 [3689 generator.createArrowFunction(3690 undefined,3691 undefined,3692 [3693 generator.createParameter(3694 undefined,3695 undefined,3696 undefined,3697 generator.createIdentifier("item"),3698 undefined,3699 undefined,3700 undefined3701 ),3702 ],3703 undefined,3704 generator.createToken(3705 generator.SyntaxKind.EqualsGreaterThanToken3706 ),3707 generator.createJsxSelfClosingElement(3708 generator.createIdentifier("item"),3709 undefined,3710 [3711 generator.createJsxAttribute(3712 generator.createIdentifier("event"),3713 generator.createIdentifier("value")3714 ),3715 ]3716 )3717 ),3718 ]3719 )3720 ),3721 ],3722 generator.createJsxClosingElement(generator.createIdentifier("div"))3723 );3724 const options: toStringOptions = {3725 members: [getter],3726 componentContext: "viewModel",3727 newComponentContext: "",3728 };3729 assert.strictEqual(3730 removeSpaces(element.toString(options)),3731 removeSpaces(`3732 <div>3733 <template v-for="item of DynamicComponent">3734 <component 3735 v-bind:is="item"3736 @event="value"3737 />3738 </template>3739 </div>3740 `),3741 type.toString()3742 );3743 });3744 });3745 });3746 mocha.describe("Import widget.", function () {3747 this.beforeEach(function () {3748 generator.setContext({3749 dirname: __dirname,3750 });3751 generator.createImportDeclaration(3752 [],3753 [],3754 generator.createImportClause(3755 generator.createIdentifier("DxWidget"),3756 undefined3757 ),3758 generator.createStringLiteral(3759 "./test-cases/declarations/src/component-input"3760 )3761 );3762 });3763 this.afterEach(function () {3764 generator.setContext(null);3765 });3766 mocha.it("<DxWidget></DxWidget> -> <dx-widget></dx-widget>", function () {3767 const element = generator.createJsxElement(3768 generator.createJsxOpeningElement(3769 generator.createIdentifier("DxWidget")3770 ),3771 [],3772 generator.createJsxClosingElement(3773 generator.createIdentifier("DxWidget")3774 )3775 );3776 assert.strictEqual(element.toString(), "<DxWidget ></DxWidget>");3777 });3778 mocha.it("<DxWidget/> -> <dx-widget/>", function () {3779 const element = generator.createJsxSelfClosingElement(3780 generator.createIdentifier("DxWidget"),3781 []3782 );3783 assert.strictEqual(element.toString(), "<DxWidget />");3784 });3785 mocha.it("Process eventChange - @event-change", function () {3786 generator.createClassDeclaration(3787 [createComponentDecorator({})],3788 [],3789 generator.createIdentifier("Widget"),3790 [],3791 [],3792 [3793 generator.createProperty(3794 [createDecorator("Event")],3795 [],3796 generator.createIdentifier("eventChange"),3797 undefined,3798 undefined,3799 undefined3800 ),3801 ]3802 );3803 const element = generator.createJsxSelfClosingElement(3804 generator.createIdentifier("Widget"),3805 [],3806 [3807 generator.createJsxAttribute(3808 generator.createIdentifier("eventChange"),3809 generator.createIdentifier("value")3810 ),3811 ]3812 );3813 assert.strictEqual(3814 element.toString({3815 members: [],3816 }),3817 `<Widget @event-change="value"/>`3818 );3819 });3820 mocha.it(3821 "Process statePropChange - @update:state-prop if stateProp is TwoWay prop",3822 function () {3823 generator.createClassDeclaration(3824 [createComponentDecorator({})],3825 [],3826 generator.createIdentifier("Widget"),3827 [],3828 [],3829 [3830 generator.createProperty(3831 [createDecorator("Event")],3832 [],3833 generator.createIdentifier("statePropChange"),3834 undefined,3835 undefined,3836 undefined3837 ),3838 generator.createProperty(3839 [createDecorator("TwoWay")],3840 [],3841 generator.createIdentifier("stateProp")3842 ),3843 ]3844 );3845 const element = generator.createJsxSelfClosingElement(3846 generator.createIdentifier("Widget"),3847 [],3848 [3849 generator.createJsxAttribute(3850 generator.createIdentifier("statePropChange"),3851 generator.createIdentifier("value")3852 ),3853 ]3854 );3855 assert.strictEqual(3856 element.toString({3857 members: [],3858 }),3859 `<Widget @update:state-prop="value"/>`3860 );3861 }3862 );3863 mocha.describe("Pass slots via attribute", function () {3864 this.beforeEach(function () {3865 generator.setContext({3866 dirname: __dirname,3867 });3868 const defaultSlot = generator.createProperty(3869 [createDecorator("Slot")],3870 [],3871 generator.createIdentifier("children")3872 );3873 const namedSlot = generator.createProperty(3874 [createDecorator("Slot")],3875 [],3876 generator.createIdentifier("namedSlot")3877 );3878 generator.createClassDeclaration(3879 [createComponentDecorator({})],3880 [],3881 generator.createIdentifier("Widget"),3882 [],3883 [],3884 [defaultSlot, namedSlot]3885 );3886 });3887 this.afterEach(function () {3888 generator.setContext(null);3889 });3890 mocha.it("Self-closing element", function () {3891 const slotProperty = generator.createProperty(3892 [createDecorator("Slot")],3893 [],3894 generator.createIdentifier("children")3895 );3896 const element = generator.createJsxSelfClosingElement(3897 generator.createIdentifier("Widget"),3898 [],3899 [3900 generator.createJsxAttribute(3901 generator.createIdentifier("children"),3902 generator.createPropertyAccess(3903 generator.createIdentifier("props"),3904 generator.createIdentifier("children")3905 )3906 ),3907 ]3908 );3909 assert.strictEqual(3910 element.toString({3911 componentContext: "",3912 newComponentContext: "",3913 members: [slotProperty],3914 }),3915 `<Widget ><slot></slot></Widget>`3916 );3917 });3918 mocha.it("Self-closing element with two slots", function () {3919 const slotProperty = generator.createProperty(3920 [createDecorator("Slot")],3921 [],3922 generator.createIdentifier("children")3923 );3924 const namedSlot = generator.createProperty(3925 [createDecorator("Slot")],3926 [],3927 generator.createIdentifier("namedSlot")3928 );3929 const element = generator.createJsxSelfClosingElement(3930 generator.createIdentifier("Widget"),3931 [],3932 [3933 generator.createJsxAttribute(3934 generator.createIdentifier("children"),3935 generator.createPropertyAccess(3936 generator.createIdentifier("props"),3937 generator.createIdentifier("children")3938 )3939 ),3940 generator.createJsxAttribute(3941 generator.createIdentifier("namedSlot"),3942 generator.createPropertyAccess(3943 generator.createIdentifier("props"),3944 generator.createIdentifier("namedSlot")3945 )3946 ),3947 ]3948 );3949 assert.strictEqual(3950 element.toString({3951 componentContext: "",3952 newComponentContext: "",3953 members: [slotProperty, namedSlot],3954 }),3955 `<Widget ><slot></slot><slot name="namedSlot"></slot></Widget>`3956 );3957 });3958 mocha.it("spread props with slot", function () {3959 const slotProperty = generator.createProperty(3960 [createDecorator("Slot")],3961 [],3962 generator.createIdentifier("children")3963 );3964 const element = generator.createJsxSelfClosingElement(3965 generator.createIdentifier("Widget"),3966 [],3967 [3968 generator.createJsxSpreadAttribute(3969 generator.createPropertyAccess(3970 generator.createIdentifier(generator.SyntaxKind.ThisKeyword),3971 generator.createIdentifier("props")3972 )3973 ),3974 ]3975 );3976 assert.strictEqual(3977 element.toString({3978 componentContext: "this",3979 newComponentContext: "",3980 members: [slotProperty],3981 }),3982 `<Widget v-bind="{...props,...{children:undefined}}"><slot></slot></Widget>`3983 );3984 });3985 mocha.it("element with closing tag", function () {3986 const slotProperty = generator.createProperty(3987 [createDecorator("Slot")],3988 [],3989 generator.createIdentifier("children")3990 );3991 const element = generator.createJsxElement(3992 generator.createJsxOpeningElement(3993 generator.createIdentifier("Widget"),3994 [],3995 [3996 generator.createJsxAttribute(3997 generator.createIdentifier("children"),3998 generator.createPropertyAccess(3999 generator.createIdentifier("props"),4000 generator.createIdentifier("children")4001 )4002 ),4003 ]4004 ),4005 [4006 generator.createJsxSelfClosingElement(4007 generator.createIdentifier("span")4008 ),4009 ],4010 generator.createJsxClosingElement(4011 generator.createIdentifier("Widget")4012 )4013 );4014 assert.strictEqual(4015 element.toString({4016 componentContext: "",4017 newComponentContext: "",4018 members: [slotProperty],4019 }),4020 `<Widget ><span /><slot></slot></Widget>`4021 );4022 });4023 });4024 mocha.describe("Pass Widget to template property", function () {4025 const getComponent = () =>4026 generator.createClassDeclaration(4027 [createDecorator(Decorators.Component)],4028 [],4029 generator.createIdentifier("ComponentWithTemplate"),4030 [],4031 [],4032 [4033 generator.createProperty(4034 [createDecorator(Decorators.Template)],4035 [],4036 generator.createIdentifier("contentTemplate")4037 ),4038 ]4039 );4040 mocha.it(4041 "Pass widget into template. self-closing element",4042 function () {4043 const component = getComponent();4044 const element = generator.createJsxSelfClosingElement(4045 generator.createIdentifier("ComponentWithTemplate"),4046 [],4047 [4048 generator.createJsxAttribute(4049 generator.createIdentifier("contentTemplate"),4050 generator.createIdentifier("DxWidget")4051 ),4052 ]4053 );4054 assert.strictEqual(4055 removeSpaces(4056 element.toString({4057 members: component.members,4058 })4059 ),4060 removeSpaces(`4061 <ComponentWithTemplate>4062 <template v-slot:contentTemplate="slotProps">4063 <DxWidget :height="slotProps.height"4064 :width="slotProps.width"4065 :children="slotProps.children"/>4066 </template>4067 </ComponentWithTemplate>4068 `)4069 );4070 }4071 );4072 mocha.it("Pass widget into template. Element", function () {4073 const component = getComponent();4074 const element = generator.createJsxElement(4075 generator.createJsxOpeningElement(4076 generator.createIdentifier("ComponentWithTemplate"),4077 [],4078 [4079 generator.createJsxAttribute(4080 generator.createIdentifier("contentTemplate"),4081 generator.createIdentifier("DxWidget")4082 ),4083 ]4084 ),4085 [],4086 generator.createJsxClosingElement(4087 generator.createIdentifier("ComponentWithTemplate")4088 )4089 );4090 assert.strictEqual(4091 removeSpaces(4092 element.toString({4093 members: component.members,4094 })4095 ),4096 removeSpaces(`4097 <ComponentWithTemplate>4098 <template v-slot:contentTemplate="slotProps">4099 <DxWidget 4100 :height="slotProps.height"4101 :width="slotProps.width"...
executed-code-coverage.ts
Source:executed-code-coverage.ts
...35 ts.createVariableStatement(36 undefined,37 ts.createVariableDeclarationList(38 [ts.createVariableDeclaration(39 ts.createIdentifier("_global"),40 undefined,41 ts.createConditional(42 ts.createBinary(43 ts.createTypeOf(ts.createIdentifier("globalThis")),44 ts.createToken(ts.SyntaxKind.ExclamationEqualsEqualsToken),45 ts.createStringLiteral("undefined")46 ),47 ts.createIdentifier("globalThis"),48 ts.createConditional(49 ts.createBinary(50 ts.createTypeOf(ts.createIdentifier("window")),51 ts.createToken(ts.SyntaxKind.ExclamationEqualsEqualsToken),52 ts.createStringLiteral("undefined")53 ),54 ts.createIdentifier("window"),55 ts.createIdentifier("global")56 )57 )58 )],59 ts.NodeFlags.Const60 )61 ),62 ts.createIf(63 ts.createPrefix(64 ts.SyntaxKind.ExclamationToken,65 ts.createPropertyAccess(66 ts.createIdentifier("_global"),67 ts.createIdentifier("_executedCode")68 )69 ),70 ts.createBlock(71 [72 ts.createExpressionStatement(ts.createBinary(73 ts.createPropertyAccess(74 ts.createIdentifier("_global"),75 ts.createIdentifier("_executedCode")76 ),77 ts.createToken(ts.SyntaxKind.EqualsToken),78 ts.createNew(79 ts.createIdentifier("Map"),80 undefined,81 []82 )83 )),84 ts.createExpressionStatement(ts.createBinary(85 ts.createPropertyAccess(86 ts.createIdentifier("_global"),87 ts.createIdentifier("_allCode")88 ),89 ts.createToken(ts.SyntaxKind.EqualsToken),90 ts.createNew(91 ts.createIdentifier("Map"),92 undefined,93 []94 )95 )),96 ts.createExpressionStatement(ts.createBinary(97 ts.createPropertyAccess(98 ts.createIdentifier("_global"),99 ts.createIdentifier("_showCodeCoverage")100 ),101 ts.createToken(ts.SyntaxKind.EqualsToken),102 ts.createFunctionExpression(103 undefined,104 undefined,105 undefined,106 undefined,107 [],108 undefined,109 ts.createBlock(110 [111 ts.createVariableStatement(112 undefined,113 ts.createVariableDeclarationList(114 [ts.createVariableDeclaration(115 ts.createIdentifier("total"),116 undefined,117 ts.createNumericLiteral("0")118 )],119 ts.NodeFlags.None120 )121 ),122 ts.createVariableStatement(123 undefined,124 ts.createVariableDeclarationList(125 [ts.createVariableDeclaration(126 ts.createIdentifier("totalExecuted"),127 undefined,128 ts.createNumericLiteral("0")129 )],130 ts.NodeFlags.None131 )132 ),133 ts.createExpressionStatement(ts.createCall(134 ts.createPropertyAccess(135 ts.createPropertyAccess(136 ts.createIdentifier("_global"),137 ts.createIdentifier("_allCode")138 ),139 ts.createIdentifier("forEach")140 ),141 undefined,142 [ts.createFunctionExpression(143 undefined,144 undefined,145 undefined,146 undefined,147 [148 ts.createParameter(149 undefined,150 undefined,151 undefined,152 ts.createIdentifier("all"),153 undefined,154 undefined,155 undefined156 ),157 ts.createParameter(158 undefined,159 undefined,160 undefined,161 ts.createIdentifier("file"),162 undefined,163 undefined,164 undefined165 )166 ],167 undefined,168 ts.createBlock(169 [170 ts.createVariableStatement(171 undefined,172 ts.createVariableDeclarationList(173 [ts.createVariableDeclaration(174 ts.createIdentifier("set"),175 undefined,176 ts.createCall(177 ts.createPropertyAccess(178 ts.createPropertyAccess(179 ts.createIdentifier("_global"),180 ts.createIdentifier("_executedCode")181 ),182 ts.createIdentifier("get")183 ),184 undefined,185 [ts.createIdentifier("file")]186 )187 )],188 ts.NodeFlags.None189 )190 ),191 ts.createVariableStatement(192 undefined,193 ts.createVariableDeclarationList(194 [ts.createVariableDeclaration(195 ts.createIdentifier("remain"),196 undefined,197 ts.createArrayLiteral(198 [],199 false200 )201 )],202 ts.NodeFlags.None203 )204 ),205 ts.createFor(206 ts.createVariableDeclarationList(207 [ts.createVariableDeclaration(208 ts.createIdentifier("j"),209 undefined,210 ts.createNumericLiteral("0")211 )],212 ts.NodeFlags.None213 ),214 ts.createBinary(215 ts.createIdentifier("j"),216 ts.createToken(ts.SyntaxKind.LessThanToken),217 ts.createPropertyAccess(218 ts.createIdentifier("all"),219 ts.createIdentifier("length")220 )221 ),222 ts.createPostfix(223 ts.createIdentifier("j"),224 ts.SyntaxKind.PlusPlusToken225 ),226 ts.createBlock(227 [228 ts.createVariableStatement(229 undefined,230 ts.createVariableDeclarationList(231 [ts.createVariableDeclaration(232 ts.createIdentifier("e"),233 undefined,234 ts.createElementAccess(235 ts.createIdentifier("all"),236 ts.createIdentifier("j")237 )238 )],239 ts.NodeFlags.None240 )241 ),242 ts.createExpressionStatement(ts.createPostfix(243 ts.createIdentifier("total"),244 ts.SyntaxKind.PlusPlusToken245 )),246 ts.createIf(247 ts.createCall(248 ts.createPropertyAccess(249 ts.createIdentifier("set"),250 ts.createIdentifier("has")251 ),252 undefined,253 [ts.createIdentifier("e")]254 ),255 ts.createBlock(256 [ts.createExpressionStatement(ts.createPostfix(257 ts.createIdentifier("totalExecuted"),258 ts.SyntaxKind.PlusPlusToken259 ))],260 true261 ),262 ts.createBlock(263 [ts.createExpressionStatement(ts.createCall(264 ts.createPropertyAccess(265 ts.createIdentifier("remain"),266 ts.createIdentifier("push")267 ),268 undefined,269 [ts.createIdentifier("e")]270 ))],271 true272 )273 )274 ],275 true276 )277 ),278 ts.createExpressionStatement(ts.createCall(279 ts.createPropertyAccess(280 ts.createIdentifier("remain"),281 ts.createIdentifier("sort")282 ),283 undefined,284 [ts.createFunctionExpression(285 undefined,286 undefined,287 undefined,288 undefined,289 [290 ts.createParameter(291 undefined,292 undefined,293 undefined,294 ts.createIdentifier("a"),295 undefined,296 undefined,297 undefined298 ),299 ts.createParameter(300 undefined,301 undefined,302 undefined,303 ts.createIdentifier("b"),304 undefined,305 undefined,306 undefined307 )308 ],309 undefined,310 ts.createBlock(311 [ts.createReturn(ts.createBinary(312 ts.createIdentifier("a"),313 ts.createToken(ts.SyntaxKind.MinusToken),314 ts.createIdentifier("b")315 ))],316 false317 )318 )]319 )),320 ts.createVariableStatement(321 undefined,322 ts.createVariableDeclarationList(323 [ts.createVariableDeclaration(324 ts.createIdentifier("percent"),325 undefined,326 ts.createBinary(327 ts.createCall(328 ts.createPropertyAccess(329 ts.createIdentifier("Math"),330 ts.createIdentifier("floor")331 ),332 undefined,333 [ts.createBinary(334 ts.createBinary(335 ts.createNumericLiteral("10000"),336 ts.createToken(ts.SyntaxKind.AsteriskToken),337 ts.createPropertyAccess(338 ts.createIdentifier("set"),339 ts.createIdentifier("size")340 )341 ),342 ts.createToken(ts.SyntaxKind.SlashToken),343 ts.createPropertyAccess(344 ts.createIdentifier("all"),345 ts.createIdentifier("length")346 )347 )]348 ),349 ts.createToken(ts.SyntaxKind.SlashToken),350 ts.createNumericLiteral("100")351 )352 )],353 ts.NodeFlags.None354 )355 ),356 ts.createVariableStatement(357 undefined,358 ts.createVariableDeclarationList(359 [ts.createVariableDeclaration(360 ts.createIdentifier("percentString"),361 undefined,362 ts.createCall(363 ts.createPropertyAccess(364 ts.createIdentifier("percent"),365 ts.createIdentifier("toFixed")366 ),367 undefined,368 [ts.createNumericLiteral("2")]369 )370 )],371 ts.NodeFlags.None372 )373 ),374 ts.createExpressionStatement(ts.createCall(375 ts.createPropertyAccess(376 ts.createIdentifier("console"),377 ts.createIdentifier("log")378 ),379 undefined,380 [ts.createBinary(381 ts.createBinary(382 ts.createBinary(383 ts.createBinary(384 ts.createBinary(385 ts.createBinary(386 ts.createBinary(387 ts.createBinary(388 ts.createBinary(389 ts.createStringLiteral("[executed code coverage]"),390 ts.createToken(ts.SyntaxKind.PlusToken),391 ts.createIdentifier("file")392 ),393 ts.createToken(ts.SyntaxKind.PlusToken),394 ts.createStringLiteral(": ")395 ),396 ts.createToken(ts.SyntaxKind.PlusToken),397 ts.createPropertyAccess(398 ts.createIdentifier("set"),399 ts.createIdentifier("size")400 )401 ),402 ts.createToken(ts.SyntaxKind.PlusToken),403 ts.createStringLiteral(" / ")404 ),405 ts.createToken(ts.SyntaxKind.PlusToken),406 ts.createPropertyAccess(407 ts.createIdentifier("all"),408 ts.createIdentifier("length")409 )410 ),411 ts.createToken(ts.SyntaxKind.PlusToken),412 ts.createStringLiteral(" ")413 ),414 ts.createToken(ts.SyntaxKind.PlusToken),415 ts.createIdentifier("percentString")416 ),417 ts.createToken(ts.SyntaxKind.PlusToken),418 ts.createStringLiteral("% ")419 ),420 ts.createToken(ts.SyntaxKind.PlusToken),421 ts.createCall(422 ts.createPropertyAccess(423 ts.createIdentifier("remain"),424 ts.createIdentifier("join")425 ),426 undefined,427 [ts.createStringLiteral(",")]428 )429 )]430 ))431 ],432 true433 )434 )]435 )),436 ts.createVariableStatement(437 undefined,438 ts.createVariableDeclarationList(439 [ts.createVariableDeclaration(440 ts.createIdentifier("percent"),441 undefined,442 ts.createBinary(443 ts.createCall(444 ts.createPropertyAccess(445 ts.createIdentifier("Math"),446 ts.createIdentifier("floor")447 ),448 undefined,449 [ts.createBinary(450 ts.createBinary(451 ts.createNumericLiteral("10000"),452 ts.createToken(ts.SyntaxKind.AsteriskToken),453 ts.createIdentifier("totalExecuted")454 ),455 ts.createToken(ts.SyntaxKind.SlashToken),456 ts.createIdentifier("total")457 )]458 ),459 ts.createToken(ts.SyntaxKind.SlashToken),460 ts.createNumericLiteral("100")461 )462 )],463 ts.NodeFlags.None464 )465 ),466 ts.createVariableStatement(467 undefined,468 ts.createVariableDeclarationList(469 [ts.createVariableDeclaration(470 ts.createIdentifier("percentString"),471 undefined,472 ts.createCall(473 ts.createPropertyAccess(474 ts.createIdentifier("percent"),475 ts.createIdentifier("toFixed")476 ),477 undefined,478 [ts.createNumericLiteral("2")]479 )480 )],481 ts.NodeFlags.None482 )483 ),484 ts.createExpressionStatement(ts.createCall(485 ts.createPropertyAccess(486 ts.createIdentifier("console"),487 ts.createIdentifier("log")488 ),489 undefined,490 [ts.createBinary(491 ts.createBinary(492 ts.createBinary(493 ts.createBinary(494 ts.createBinary(495 ts.createBinary(496 ts.createStringLiteral("[executed code coverage]total: "),497 ts.createToken(ts.SyntaxKind.PlusToken),498 ts.createIdentifier("totalExecuted")499 ),500 ts.createToken(ts.SyntaxKind.PlusToken),501 ts.createStringLiteral(" / ")502 ),503 ts.createToken(ts.SyntaxKind.PlusToken),504 ts.createIdentifier("total")505 ),506 ts.createToken(ts.SyntaxKind.PlusToken),507 ts.createStringLiteral(" ")508 ),509 ts.createToken(ts.SyntaxKind.PlusToken),510 ts.createIdentifier("percentString")511 ),512 ts.createToken(ts.SyntaxKind.PlusToken),513 ts.createStringLiteral("%")514 )]515 ))516 ],517 true518 )519 )520 )),521 ],522 true523 ),524 undefined525 ),526 ts.createVariableStatement(527 undefined,528 ts.createVariableDeclarationList(529 [ts.createVariableDeclaration(530 ts.createIdentifier("_executedCodeLines"),531 undefined,532 ts.createNew(533 ts.createIdentifier("Set"),534 undefined,535 []536 )537 )],538 ts.NodeFlags.None539 )540 ),541 ts.createExpressionStatement(ts.createCall(542 ts.createPropertyAccess(543 ts.createPropertyAccess(544 ts.createIdentifier("_global"),545 ts.createIdentifier("_executedCode")546 ),547 ts.createIdentifier("set")548 ),549 undefined,550 [551 ts.createStringLiteral(fileName),552 ts.createIdentifier("_executedCodeLines")553 ]554 )),555 ts.createExpressionStatement(ts.createCall(556 ts.createPropertyAccess(557 ts.createPropertyAccess(558 ts.createIdentifier("_global"),559 ts.createIdentifier("_allCode")560 ),561 ts.createIdentifier("set")562 ),563 undefined,564 [565 ts.createStringLiteral(fileName),566 ts.createArrayLiteral(567 Array.from(allCode).map((a) => ts.createNumericLiteral(a.toString())),568 false569 )570 ]571 )),572 ...sourceFile.statements,573 ])574 return result575}576function transformStatements(577 sourceFile: ts.SourceFile,578 node: { statements: ts.NodeArray<ts.Statement> },579 allCode: Set<number>,580 parentStart?: number,581) {582 const disabledStatements: ts.Statement[] = []583 const statements: ts.Statement[] = []584 for (const statement of node.statements) {585 if (isNotExecutableStatement(statement)) {586 statements.push(statement)587 continue588 }589 let start = parentStart590 if (statement.pos < 0) {591 if (parentStart === undefined) {592 statements.push(statement)593 continue594 } else {595 start = parentStart596 }597 } else {598 start = statement.getStart(sourceFile)599 }600 const { line } = ts.getLineAndCharacterOfPosition(sourceFile, start)601 allCode.add(line + 1)602 statements.push(603 ts.createExpressionStatement(ts.createCall(604 ts.createPropertyAccess(605 ts.createIdentifier("_executedCodeLines"),606 ts.createIdentifier("add")607 ),608 undefined,609 [ts.createNumericLiteral((line + 1).toString())]610 )),611 statement,612 )613 }614 node.statements = ts.createNodeArray(statements)615 return disabledStatements...
Using AI Code Generation
1const createIdentifier = require('ts-auto-mock/createIdentifier');2const identifier = createIdentifier('test1');3console.log(identifier);4const createIdentifier = require('ts-auto-mock/createIdentifier');5const identifier = createIdentifier('test2');6console.log(identifier);7const createIdentifier = require('ts-auto-mock/createIdentifier');8const identifier = createIdentifier('test3');9console.log(identifier);10const createIdentifier = require('ts-auto-mock/createIdentifier');11const identifier = createIdentifier('test4');12console.log(identifier);13const createIdentifier = require('ts-auto-mock/createIdentifier');14const identifier = createIdentifier('test5');15console.log(identifier);16const createIdentifier = require('ts-auto-mock/createIdentifier');17const identifier = createIdentifier('test6');18console.log(identifier);19const createIdentifier = require('ts-auto-mock/createIdentifier');20const identifier = createIdentifier('test7');21console.log(identifier);22const createIdentifier = require('ts-auto-mock/createIdentifier');23const identifier = createIdentifier('test8');24console.log(identifier);25const createIdentifier = require('ts-auto-mock/createIdentifier');26const identifier = createIdentifier('test9');27console.log(identifier);28const createIdentifier = require('ts-auto-mock/createIdentifier');29const identifier = createIdentifier('test10');30console.log(identifier);31const createIdentifier = require('ts-auto-mock/createIdentifier');32const identifier = createIdentifier('test11');33console.log(identifier);
Using AI Code Generation
1import { createIdentifier } from 'ts-auto-mock';2const identifier = createIdentifier('Test');3import { createIdentifier } from 'ts-auto-mock';4const identifier = createIdentifier('Test');5import { createIdentifier } from 'ts-auto-mock';6const identifier = createIdentifier('Test');7import { createIdentifier } from 'ts-auto-mock';8const identifier = createIdentifier('Test');9import { createIdentifier } from 'ts-auto-mock';10const identifier = createIdentifier('Test');11import { createIdentifier } from 'ts-auto-mock';12const identifier = createIdentifier('Test');13import { createIdentifier } from 'ts-auto-mock';14const identifier = createIdentifier('Test');15import { createIdentifier } from 'ts-auto-mock';16const identifier = createIdentifier('Test');
Using AI Code Generation
1const mock = createIdentifier('test1', 'test1.ts');2console.log(mock);3const mock = createIdentifier('test2', 'test2.ts');4console.log(mock);5export class test1 {6 id: number;7 name: string;8 constructor(id: number, name: string) {9 this.id = id;10 this.name = name;11 }12}13export class test2 {14 id: number;15 name: string;16 constructor(id: number, name: string) {17 this.id = id;18 this.name = name;19 }20}
Using AI Code Generation
1import { createIdentifier } from 'ts-auto-mock/extension';2export const test1 = createIdentifier('test1');3import { createIdentifier } from 'ts-auto-mock/extension';4export const test2 = createIdentifier('test2');5import { createIdentifier } from 'ts-auto-mock/extension';6export const test3 = createIdentifier('test3');7import { createIdentifier } from 'ts-auto-mock/extension';8export const test4 = createIdentifier('test4');9import { createIdentifier } from 'ts-auto-mock/extension';10export const test5 = createIdentifier('test5');11import { createIdentifier } from 'ts-auto-mock/extension';12export const test6 = createIdentifier('test6');13import { createIdentifier } from 'ts-auto-mock/extension';14export const test7 = createIdentifier('test7');15import { createIdentifier } from 'ts-auto-mock/extension';16export const test8 = createIdentifier('test8');17import { createIdentifier } from 'ts-auto-mock/extension';
Using AI Code Generation
1import { createIdentifier } from 'ts-auto-mock';2const identifier = createIdentifier('IInterfaceName');3export interface IInterfaceName {4 property1: string;5 property2: string;6}7export const myMock = createMock<IInterfaceName>(identifier);
Using AI Code Generation
1import { createIdentifier } from 'ts-auto-mock/extension';2import { ClassA } from 'path/to/ClassA';3const classAIdentifier = createIdentifier<ClassA>('ClassA');4import { createIdentifier } from 'ts-auto-mock/extension';5import { ClassA } from 'path/to/ClassA';6const classAIdentifier = createIdentifier<ClassA>('ClassA');7import { createIdentifier } from 'ts-auto-mock/extension';8import { ClassA } from 'path/to/ClassA';9const classAIdentifier = createIdentifier<ClassA>('ClassA');10import { createIdentifier } from 'ts-auto-mock/extension';11import { ClassA } from 'path/to/ClassA';12const classAIdentifier = createIdentifier<ClassA>('ClassA');13import { createIdentifier } from 'ts-auto-mock/extension';14import { ClassA } from 'path/to/ClassA';15const classAIdentifier = createIdentifier<ClassA>('ClassA');16import { createIdentifier } from 'ts-auto-mock/extension';17import { ClassA } from 'path/to/ClassA';18const classAIdentifier = createIdentifier<ClassA>('ClassA');19import { createIdentifier } from 'ts-auto-mock/extension';20import { ClassA } from 'path/to/ClassA';
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!