rules.test.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. const { RuleTester } = require('eslint')
  2. const preferKebabUrl = require('./prefer-kebab-url')
  3. const noUnnecessaryTrans = require('./no-unnecessary-trans')
  4. const shouldUnescapeTrans = require('./should-unescape-trans')
  5. const noGeneratedEditorThemes = require('./no-generated-editor-themes')
  6. const viDoMockValidPath = require('./require-vi-doMock-valid-path')
  7. const ruleTester = new RuleTester({
  8. parser: require.resolve('@typescript-eslint/parser'),
  9. parserOptions: {
  10. ecmaVersion: 'latest',
  11. ecmaFeatures: { jsx: true },
  12. },
  13. })
  14. ruleTester.run('prefer-kebab-url', preferKebabUrl, {
  15. valid: [
  16. { code: `app.get('/foo-bar')` },
  17. { code: `app.get('/foo-bar/:id')` },
  18. { code: `router.post('/foo-bar')` },
  19. { code: `router.get('/foo-bar/:id/:name/:age')` },
  20. { code: `webRouter.get('/foo-bar/:user_id/(ProjectName)/get-info')` },
  21. { code: `webApp.post('/foo-bar/:user_id/(ProjectName)/get-info')` },
  22. {
  23. code: `router.get(/^\\/download\\/project\\/([^/]*)\\/output\\/output\\.pdf$/)`,
  24. },
  25. {
  26. code: `webRouter.get(/^\\/project\\/([^/]*)\\/user\\/([0-9a-f]+)\\/build\\/([0-9a-f-]+)\\/output\\/(.*)$/)`,
  27. },
  28. ],
  29. invalid: [
  30. {
  31. code: `app.get('/fooBar')`,
  32. errors: [{ message: 'Route path should be in kebab-case.' }],
  33. },
  34. {
  35. code: `app.get('/fooBar/:id')`,
  36. errors: [{ message: 'Route path should be in kebab-case.' }],
  37. },
  38. {
  39. code: `webRouter.get('/foo_bar/:id/FooBar/:name/fooBar')`,
  40. errors: [{ message: 'Route path should be in kebab-case.' }],
  41. },
  42. {
  43. code: `router.get(/^\\/downLoad\\/pro-ject\\/([^/]*)\\/OutPut\\/out-put\\.pdf$/)`,
  44. errors: [{ message: 'Route path should be in kebab-case.' }],
  45. },
  46. ],
  47. })
  48. ruleTester.run('no-unnecessary-trans', noUnnecessaryTrans, {
  49. valid: [
  50. { code: `<Trans i18nKey="test" components={{ strong: <strong/> }}/>` },
  51. ],
  52. invalid: [
  53. {
  54. code: `<Trans i18nKey="test" values={{ test: 'foo '}}/>`,
  55. errors: [{ message: `Use t('…') when there are no components` }],
  56. },
  57. {
  58. code: `<Trans i18nKey="test" />`,
  59. errors: [{ message: `Use t('…') when there are no components` }],
  60. output: `{t('test')}`,
  61. },
  62. ],
  63. })
  64. ruleTester.run('should-unescape-trans', shouldUnescapeTrans, {
  65. valid: [
  66. {
  67. code: `<Trans i18nKey="test" components={{ strong: <strong/> }}/>`,
  68. },
  69. {
  70. code: `<Trans i18nKey="test" values={{ foo: 'bar' }} components={{ strong: <strong/> }} shouldUnescape tOptions={{ interpolation: { escapeValue: true } }}/>`,
  71. },
  72. ],
  73. invalid: [
  74. {
  75. code: `<Trans i18nKey="test" values={{ foo: 'bar' }} components={{ strong: <strong/> }} />`,
  76. errors: [{ message: 'Trans with values must have shouldUnescape' }],
  77. output: `<Trans i18nKey="test" values={{ foo: 'bar' }}\nshouldUnescape components={{ strong: <strong/> }} />`,
  78. },
  79. {
  80. code: `<Trans i18nKey="test" values={{ foo: 'bar' }} components={{ strong: <strong/> }} shouldUnescape />`,
  81. errors: [
  82. {
  83. message:
  84. 'Trans with shouldUnescape must have tOptions.interpolation.escapeValue',
  85. },
  86. ],
  87. output: `<Trans i18nKey="test" values={{ foo: 'bar' }} components={{ strong: <strong/> }} shouldUnescape\ntOptions={{ interpolation: { escapeValue: true } }} />`,
  88. },
  89. ],
  90. })
  91. const noGeneratedEditorThemesError =
  92. 'EditorView.theme and EditorView.baseTheme each add CSS to the page for every instance of the theme. Store the theme in a variable and reuse it instead.'
  93. ruleTester.run('no-generated-editor-themes', noGeneratedEditorThemes, {
  94. valid: [
  95. {
  96. code: `EditorView.theme({ '.cm-editor': { color: 'black' } })`,
  97. },
  98. {
  99. code: `const theme = EditorView.theme({ '.cm-editor': { color: 'black' } })`,
  100. },
  101. ],
  102. invalid: [
  103. {
  104. code: `function createTheme() { return EditorView.theme({ '.cm-editor': { color: 'black' } }) }`,
  105. errors: [
  106. {
  107. message: noGeneratedEditorThemesError,
  108. },
  109. ],
  110. },
  111. {
  112. code: `() => EditorView.theme({ '.cm-editor': { color: 'black' } })`,
  113. errors: [
  114. {
  115. message: noGeneratedEditorThemesError,
  116. },
  117. ],
  118. },
  119. {
  120. code: `class Foo { createTheme() { return EditorView.theme({ '.cm-editor': { color: 'black' } }) } }`,
  121. errors: [
  122. {
  123. message: noGeneratedEditorThemesError,
  124. },
  125. ],
  126. },
  127. ],
  128. })
  129. ruleTester.run('domock-require-valid-path', viDoMockValidPath, {
  130. valid: [
  131. {
  132. code: 'vi.doMock("./require-vi-doMock-valid-path.js")',
  133. filename: __filename
  134. },
  135. {
  136. code: 'const filename = "./require-vi-doMock-valid-path.js"; vi.doMock(filename);',
  137. filename: __filename
  138. }
  139. ],
  140. invalid: [{
  141. code: "vi.doMock('./require-vi-doMock-valid-path2')",
  142. filename: __filename,
  143. errors: [
  144. {
  145. message: 'The path "./require-vi-doMock-valid-path2" in vi.doMock() cannot be resolved relative to the current file.'}
  146. ]
  147. }, {
  148. code: 'const filename = "./require-vi-doMock-valid-path2.js"; vi.doMock(filename);',
  149. filename: __filename,
  150. errors: [
  151. {
  152. message: 'The first argument of vi.doMock() must be (or resolve to) a string literal representing a path.'}
  153. ]
  154. }]
  155. })