getClassList.test.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. import resolveConfig from '../src/public/resolve-config'
  2. import plugin from '../src/public/create-plugin'
  3. import { createContext } from '../src/lib/setupContextUtils'
  4. it('should generate every possible class, without variants', () => {
  5. let config = {}
  6. let context = createContext(resolveConfig(config))
  7. let classes = context.getClassList()
  8. expect(classes).toBeInstanceOf(Array)
  9. // Verify we have a `container` for the 'components' section.
  10. expect(classes).toContain('container')
  11. // Verify we handle the DEFAULT case correctly
  12. expect(classes).toContain('border')
  13. // Verify we handle negative values correctly
  14. expect(classes).toContain('-inset-1/4')
  15. expect(classes).toContain('-m-0')
  16. expect(classes).not.toContain('-uppercase')
  17. expect(classes).not.toContain('-opacity-50')
  18. config = { theme: { extend: { margin: { DEFAULT: '5px' } } } }
  19. context = createContext(resolveConfig(config))
  20. classes = context.getClassList()
  21. expect(classes).not.toContain('-m-DEFAULT')
  22. })
  23. it('should generate every possible class while handling negatives and prefixes', () => {
  24. let config = { prefix: 'tw-' }
  25. let context = createContext(resolveConfig(config))
  26. let classes = context.getClassList()
  27. expect(classes).toBeInstanceOf(Array)
  28. // Verify we have a `container` for the 'components' section.
  29. expect(classes).toContain('tw-container')
  30. // Verify we handle the DEFAULT case correctly
  31. expect(classes).toContain('tw-border')
  32. // Verify we handle negative values correctly
  33. expect(classes).toContain('-tw-inset-1/4')
  34. expect(classes).toContain('-tw-m-0')
  35. expect(classes).not.toContain('-tw-uppercase')
  36. expect(classes).not.toContain('-tw-opacity-50')
  37. // These utilities do work but there's no reason to generate
  38. // them alongside the `-{prefix}-{utility}` versions
  39. expect(classes).not.toContain('tw--inset-1/4')
  40. expect(classes).not.toContain('tw--m-0')
  41. config = {
  42. prefix: 'tw-',
  43. theme: { extend: { margin: { DEFAULT: '5px' } } },
  44. }
  45. context = createContext(resolveConfig(config))
  46. classes = context.getClassList()
  47. expect(classes).not.toContain('-tw-m-DEFAULT')
  48. })
  49. it('should not generate utilities with opacity by default', () => {
  50. let config = {}
  51. let context = createContext(resolveConfig(config))
  52. let classes = context.getClassList()
  53. expect(classes).not.toContain('bg-red-500/50')
  54. })
  55. it('should not include metadata by default', () => {
  56. let config = {}
  57. let context = createContext(resolveConfig(config))
  58. let classes = context.getClassList()
  59. expect(classes.every((cls) => typeof cls === 'string')).toEqual(true)
  60. expect(classes).toContain('bg-red-500')
  61. expect(classes).toContain('text-2xl')
  62. })
  63. it('should generate utilities with modifier data when requested', () => {
  64. let config = {}
  65. let context = createContext(resolveConfig(config))
  66. let classes = context.getClassList({ includeMetadata: true })
  67. expect(classes).not.toContain('bg-red-500')
  68. expect(classes).not.toContain('text-2xl')
  69. expect(classes).toContainEqual([
  70. 'bg-red-500',
  71. {
  72. modifiers: [
  73. '0',
  74. '5',
  75. '10',
  76. '15',
  77. '20',
  78. '25',
  79. '30',
  80. '35',
  81. '40',
  82. '45',
  83. '50',
  84. '55',
  85. '60',
  86. '65',
  87. '70',
  88. '75',
  89. '80',
  90. '85',
  91. '90',
  92. '95',
  93. '100',
  94. ],
  95. },
  96. ])
  97. expect(classes).toContainEqual([
  98. 'text-2xl',
  99. {
  100. modifiers: [
  101. '3',
  102. '4',
  103. '5',
  104. '6',
  105. '7',
  106. '8',
  107. '9',
  108. '10',
  109. 'none',
  110. 'tight',
  111. 'snug',
  112. 'normal',
  113. 'relaxed',
  114. 'loose',
  115. ],
  116. },
  117. ])
  118. })
  119. it('should generate plugin-defined utilities with modifier data when requested', () => {
  120. let config = {
  121. plugins: [
  122. plugin(function ({ matchUtilities }) {
  123. matchUtilities(
  124. {
  125. foo: (value) => {
  126. return { margin: value }
  127. },
  128. },
  129. {
  130. values: { xl: '32px' },
  131. modifiers: { bar: 'something' },
  132. }
  133. )
  134. matchUtilities(
  135. {
  136. 'foo-negative': (value) => {
  137. return { margin: value }
  138. },
  139. },
  140. {
  141. values: { xl: '32px' },
  142. modifiers: { bar: 'something' },
  143. supportsNegativeValues: true,
  144. }
  145. )
  146. }),
  147. ],
  148. }
  149. let context = createContext(resolveConfig(config))
  150. let classes = context.getClassList({ includeMetadata: true })
  151. expect(classes).toContainEqual(['foo-xl', { modifiers: ['bar'] }])
  152. expect(classes).toContainEqual(['foo-negative-xl', { modifiers: ['bar'] }])
  153. expect(classes).toContainEqual(['-foo-negative-xl', { modifiers: ['bar'] }])
  154. expect(classes).not.toContain('foo-xl')
  155. expect(classes).not.toContain('-foo-xl')
  156. expect(classes).not.toContainEqual(['-foo-xl', { modifiers: ['bar'] }])
  157. })
  158. it('should not generate utilities with opacity even if safe-listed', () => {
  159. let config = {
  160. safelist: [
  161. {
  162. pattern: /^bg-red-(400|500)(\/(40|50))?$/,
  163. },
  164. ],
  165. }
  166. let context = createContext(resolveConfig(config))
  167. let classes = context.getClassList()
  168. expect(classes).not.toContain('bg-red-500/50')
  169. })
  170. it('should not generate utilities that are set to undefined or null to so that they are removed', () => {
  171. let config = {
  172. theme: {
  173. extend: {
  174. colors: {
  175. red: null,
  176. green: undefined,
  177. blue: {
  178. 100: null,
  179. 200: undefined,
  180. },
  181. },
  182. },
  183. },
  184. safelist: [
  185. {
  186. pattern: /^bg-(red|green|blue)-.*$/,
  187. },
  188. ],
  189. }
  190. let context = createContext(resolveConfig(config))
  191. let classes = context.getClassList()
  192. expect(classes).not.toContain('bg-red-100') // Red is `null`
  193. expect(classes).not.toContain('bg-green-100') // Green is `undefined`
  194. expect(classes).not.toContain('bg-blue-100') // Blue.100 is `null`
  195. expect(classes).not.toContain('bg-blue-200') // Blue.200 is `undefined`
  196. expect(classes).toContain('bg-blue-50')
  197. expect(classes).toContain('bg-blue-300')
  198. })