Bluesky app fork with some witchin' additions 馃挮
witchsky.app
bluesky
fork
client
1const {RuleTester} = require('eslint')
2const tseslint = require('typescript-eslint')
3const avoidUnwrappedText = require('../avoid-unwrapped-text')
4
5const ruleTester = new RuleTester({
6 languageOptions: {
7 parser: tseslint.parser,
8 parserOptions: {
9 ecmaFeatures: {
10 jsx: true,
11 },
12 ecmaVersion: 'latest',
13 sourceType: 'module',
14 },
15 },
16})
17
18describe('avoid-unwrapped-text', () => {
19 const tests = {
20 valid: [
21 {
22 code: `
23<Text>
24 foo
25</Text>
26 `,
27 },
28
29 {
30 code: `
31<Text>
32 <Trans>
33 foo
34 </Trans>
35</Text>
36 `,
37 },
38
39 {
40 code: `
41<Text>
42 <>
43 foo
44 </>
45</Text>
46 `,
47 },
48
49 {
50 code: `
51<Text>
52 {foo && <Trans>foo</Trans>}
53</Text>
54 `,
55 },
56
57 {
58 code: `
59<Text>
60 {foo ? <Trans>foo</Trans> : <Trans>bar</Trans>}
61</Text>
62 `,
63 },
64
65 {
66 code: `
67<Trans>
68 <Text>
69 foo
70 </Text>
71</Trans>
72 `,
73 },
74
75 {
76 code: `
77<Trans>
78 {foo && <Text>foo</Text>}
79</Trans>
80 `,
81 },
82
83 {
84 code: `
85<Trans>
86 {foo ? <Text>foo</Text> : <Text>bar</Text>}
87</Trans>
88 `,
89 },
90
91 {
92 code: `
93<CustomText>
94 foo
95</CustomText>
96 `,
97 },
98
99 {
100 code: `
101<CustomText>
102 <Trans>
103 foo
104 </Trans>
105</CustomText>
106 `,
107 },
108
109 {
110 code: `
111<Text>
112 {bar}
113</Text>
114 `,
115 },
116
117 {
118 code: `
119<View>
120 {bar}
121</View>
122 `,
123 },
124
125 {
126 code: `
127<Text>
128 foo {bar}
129</Text>
130 `,
131 },
132
133 {
134 code: `
135<View>
136 <Text>
137 foo
138 </Text>
139</View>
140 `,
141 },
142
143 {
144 code: `
145<View>
146 <Text>
147 {bar}
148 </Text>
149</View>
150 `,
151 },
152
153 {
154 code: `
155<View>
156 <Text>
157 foo {bar}
158 </Text>
159</View>
160 `,
161 },
162
163 {
164 code: `
165<View>
166 <CustomText>
167 foo
168 </CustomText>
169</View>
170 `,
171 },
172
173 {
174 code: `
175<View prop={
176 <Text>foo</Text>
177}>
178 <Bar />
179</View>
180 `,
181 },
182
183 {
184 code: `
185<View prop={
186 foo && <Text>foo</Text>
187}>
188 <Bar />
189</View>
190 `,
191 },
192
193 {
194 code: `
195<View prop={
196 foo ? <Text>foo</Text> : <Text>bar</Text>
197}>
198 <Bar />
199</View>
200 `,
201 },
202
203 {
204 code: `
205<View propText={
206 <Trans><Text>foo</Text></Trans>
207}>
208 <Bar />
209</View>
210 `,
211 },
212
213 {
214 code: `
215<View prop={
216 <Text><Trans>foo</Trans></Text>
217}>
218 <Bar />
219</View>
220 `,
221 },
222
223 {
224 code: `
225<Foo propText={
226 <Trans>foo</Trans>
227}>
228 <Bar />
229</Foo>
230 `,
231 },
232
233 {
234 code: `
235<Foo propText={
236 foo && <Trans>foo</Trans>
237}>
238 <Bar />
239</Foo>
240 `,
241 },
242
243 {
244 code: `
245<Foo propText={
246 foo ? <Trans>foo</Trans> : <Trans>bar</Trans>
247}>
248 <Bar />
249</Foo>
250 `,
251 },
252
253 {
254 code: `
255function Stuff() {
256 return <Text>foo</Text>
257}
258 `,
259 },
260
261 {
262 code: `
263function Stuff({ foo }) {
264 return <View>{foo}</View>
265}
266 `,
267 },
268
269 {
270 code: `
271function MyText() {
272 return <Text>foo</Text>
273}
274 `,
275 },
276
277 {
278 code: `
279function MyText({ foo }) {
280 if (foo) {
281 return <Text>foo</Text>
282 }
283 return <Text>foo</Text>
284}
285 `,
286 },
287
288 {
289 code: `
290<View>
291 <Text>{'foo'}</Text>
292</View>
293 `,
294 },
295
296 {
297 code: `
298<View>
299 <Text>{foo + 'foo'}</Text>
300</View>
301 `,
302 },
303
304 {
305 code: `
306<View>
307 <Text><Trans>{'foo'}</Trans></Text>
308</View>
309 `,
310 },
311
312 {
313 code: `
314<View>
315 {foo['bar'] && <Bar />}
316</View>
317 `,
318 },
319
320 {
321 code: `
322<View>
323 {(foo === 'bar') && <Bar />}
324</View>
325 `,
326 },
327
328 {
329 code: `
330<View>
331 {(foo !== 'bar') && <Bar />}
332</View>
333 `,
334 },
335
336 {
337 code: `
338<View>
339 <Text>{\`foo\`}</Text>
340</View>
341 `,
342 },
343
344 {
345 code: `
346<View>
347 <Text><Trans>{\`foo\`}</Trans></Text>
348</View>
349 `,
350 },
351
352 {
353 code: `
354<View>
355 <Text>{_(msg\`foo\`)}</Text>
356</View>
357 `,
358 },
359
360 {
361 code: `
362<View>
363 <Text><Trans>{_(msg\`foo\`)}</Trans></Text>
364</View>
365 `,
366 },
367
368 {
369 code: `
370<Foo>
371 <View prop={stuff('foo')}>
372 <Bar />
373 </View>
374</Foo>
375 `,
376 },
377
378 {
379 code: `
380<Foo>
381 <View onClick={() => stuff('foo')}>
382 <Bar />
383 </View>
384</Foo>
385 `,
386 },
387
388 {
389 code: `
390<View>
391 {renderItem('foo')}
392</View>
393 `,
394 },
395
396 {
397 code: `
398<View>
399 {foo === 'foo' && <Bar />}
400</View>
401 `,
402 },
403
404 {
405 code: `
406<View>
407 {foo['foo'] && <Bar />}
408</View>
409 `,
410 },
411
412 {
413 code: `
414<View>
415 {check('foo') && <Bar />}
416</View>
417 `,
418 },
419
420 {
421 code: `
422<View>
423 {foo.bar && <Bar />}
424</View>
425 `,
426 },
427
428 {
429 code: `
430<Text>
431 <Trans>{renderItem('foo')}</Trans>
432</Text>
433 `,
434 },
435
436 {
437 code: `
438<View>
439 {null}
440</View>
441 `,
442 },
443
444 {
445 code: `
446<Text>
447 <Trans>{null}</Trans>
448</Text>
449 `,
450 },
451 ],
452
453 invalid: [
454 {
455 code: `
456<View> </View>
457 `,
458 errors: 1,
459 },
460
461 {
462 code: `
463<View>
464 foo
465</View>
466 `,
467 errors: 1,
468 },
469
470 {
471 code: `
472<View>
473 <>
474 foo
475 </>
476</View>
477 `,
478 errors: 1,
479 },
480
481 {
482 code: `
483<View>
484 <Trans>
485 foo
486 </Trans>
487</View>
488 `,
489 errors: 1,
490 },
491
492 {
493 code: `
494<View>
495 {foo && <Trans>foo</Trans>}
496</View>
497 `,
498 errors: 1,
499 },
500
501 {
502 code: `
503<View>
504 {foo ? <Trans>foo</Trans> : <Trans>bar</Trans>}
505</View>
506 `,
507 errors: 2,
508 },
509
510 {
511 code: `
512<Trans>
513 <View>
514 foo
515 </View>
516</Trans>
517 `,
518 errors: 1,
519 },
520
521 {
522 code: `
523<View>
524 foo {bar}
525</View>
526 `,
527 errors: 1,
528 },
529
530 {
531 code: `
532<View>
533 <View>
534 foo
535 </View>
536</View>
537 `,
538 errors: 1,
539 },
540
541 {
542 code: `
543<Text>
544 <View>
545 foo
546 </View>
547</Text>
548 `,
549 errors: 1,
550 },
551
552 {
553 code: `
554<Text prop={
555 <View>foo</View>
556}>
557 <Bar />
558</Text>
559 `,
560 errors: 1,
561 },
562
563 {
564 code: `
565<Text prop={
566 foo && <View>foo</View>
567}>
568 <Bar />
569</Text>
570 `,
571 errors: 1,
572 },
573
574 {
575 code: `
576<Text prop={
577 foo ? <View>foo</View> : <View>bar</View>
578}>
579 <Bar />
580</Text>
581 `,
582 errors: 2,
583 },
584
585 {
586 code: `
587<Foo prop={
588 <Trans>foo</Trans>
589}>
590 <Bar />
591</Foo>
592 `,
593 errors: 1,
594 },
595
596 {
597 code: `
598function MyText() {
599 return <Foo />
600}
601 `,
602 errors: 1,
603 },
604
605 {
606 code: `
607function MyText({ foo }) {
608 return <Foo>{foo}</Foo>
609}
610 `,
611 errors: 1,
612 },
613
614 {
615 code: `
616function MyText({ foo }) {
617 if (foo) {
618 return <Foo>{foo}</Foo>
619 }
620 return <Text>foo</Text>
621}
622 `,
623 errors: 1,
624 },
625
626 {
627 code: `
628<View>
629 {'foo'}
630</View>
631 `,
632 errors: 1,
633 },
634
635 {
636 code: `
637<View>
638 {foo && 'foo'}
639</View>
640 `,
641 errors: 1,
642 },
643
644 {
645 code: `
646<View>
647 <Trans>{'foo'}</Trans>
648</View>
649 `,
650 errors: 1,
651 },
652
653 {
654 code: `
655<View>
656 {foo && <Trans>{'foo'}</Trans>}
657</View>
658 `,
659 errors: 1,
660 },
661
662 {
663 code: `
664<View>
665 {10}
666</View>
667 `,
668 errors: 1,
669 },
670
671 {
672 code: `
673<View>
674 <Trans>{10}</Trans>
675</View>
676 `,
677 errors: 1,
678 },
679
680 {
681 code: `
682<View>
683 <Trans>{foo + 10}</Trans>
684</View>
685 `,
686 errors: 1,
687 },
688
689 {
690 code: `
691<View>
692 {\`foo\`}
693</View>
694 `,
695 errors: 1,
696 },
697
698 {
699 code: `
700<View>
701 <Trans>{\`foo\`}</Trans>
702</View>
703 `,
704 errors: 1,
705 },
706
707 {
708 code: `
709<View>
710 <Trans>{foo + \`foo\`}</Trans>
711</View>
712 `,
713 errors: 1,
714 },
715
716 {
717 code: `
718<View>
719 {_(msg\`foo\`)}
720</View>
721 `,
722 errors: 1,
723 },
724
725 {
726 code: `
727<View>
728 {foo + _(msg\`foo\`)}
729</View>
730 `,
731 errors: 1,
732 },
733
734 {
735 code: `
736<View>
737 <Trans>{_(msg\`foo\`)}</Trans>
738</View>
739 `,
740 errors: 1,
741 },
742
743 {
744 code: `
745<View>
746 <Trans>{foo + _(msg\`foo\`)}</Trans>
747</View>
748 `,
749 errors: 1,
750 },
751
752 {
753 code: `
754<View>
755 <Trans>foo</Trans>
756</View>
757 `,
758 errors: 1,
759 },
760
761 {
762 code: `
763<View>
764 <Trans><Trans>foo</Trans></Trans>
765</View>
766 `,
767 errors: 1,
768 },
769
770 {
771 code: `
772<View>
773 <Trans>{foo}</Trans>
774</View>
775 `,
776 errors: 1,
777 },
778
779 {
780 code: `
781<View prop={
782 <Trans><Text>foo</Text></Trans>
783}>
784 <Bar />
785</View>
786 `,
787 errors: 1,
788 },
789 ],
790 }
791
792 // For easier local testing
793 if (!process.env.CI) {
794 let only = []
795 let skipped = []
796 ;[...tests.valid, ...tests.invalid].forEach(t => {
797 if (t.skip) {
798 delete t.skip
799 skipped.push(t)
800 }
801 if (t.only) {
802 delete t.only
803 only.push(t)
804 }
805 })
806 const predicate = t => {
807 if (only.length > 0) {
808 return only.indexOf(t) !== -1
809 }
810 if (skipped.length > 0) {
811 return skipped.indexOf(t) === -1
812 }
813 return true
814 }
815 tests.valid = tests.valid.filter(predicate)
816 tests.invalid = tests.invalid.filter(predicate)
817 }
818 ruleTester.run('avoid-unwrapped-text', avoidUnwrappedText, tests)
819})