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