important-boolean.test.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import fs from 'fs'
  2. import path from 'path'
  3. import * as sharedState from '../src/lib/sharedState'
  4. import { run, css, html } from './util/run'
  5. test('important boolean', () => {
  6. let config = {
  7. important: true,
  8. darkMode: 'class',
  9. content: [path.resolve(__dirname, './important-boolean.test.html')],
  10. corePlugins: { preflight: false },
  11. plugins: [
  12. function ({ addComponents, addUtilities }) {
  13. addComponents(
  14. {
  15. '.btn': {
  16. button: 'yes',
  17. },
  18. },
  19. { respectImportant: true }
  20. )
  21. addComponents(
  22. {
  23. '@font-face': {
  24. 'font-family': 'Inter',
  25. },
  26. '@page': {
  27. margin: '1cm',
  28. },
  29. },
  30. { respectImportant: true }
  31. )
  32. addUtilities(
  33. {
  34. '.custom-util': {
  35. button: 'no',
  36. },
  37. },
  38. { respectImportant: false }
  39. )
  40. },
  41. ],
  42. }
  43. let input = css`
  44. @tailwind base;
  45. @tailwind components;
  46. @layer components {
  47. .custom-component {
  48. @apply font-bold;
  49. }
  50. .custom-important-component {
  51. @apply text-center !important;
  52. }
  53. }
  54. @tailwind utilities;
  55. `
  56. return run(input, config).then((result) => {
  57. let expectedPath = path.resolve(__dirname, './important-boolean.test.css')
  58. let expected = fs.readFileSync(expectedPath, 'utf8')
  59. expect(result.css).toMatchFormattedCss(expected)
  60. })
  61. })
  62. // This is in a describe block so we can use `afterEach` :)
  63. describe('duplicate elision', () => {
  64. let filePath = path.resolve(__dirname, './important-boolean-duplicates.test.html')
  65. afterEach(async () => await fs.promises.unlink(filePath))
  66. test('important rules are not duplicated when rebuilding', async () => {
  67. let config = {
  68. important: true,
  69. content: [filePath],
  70. }
  71. await fs.promises.writeFile(
  72. config.content[0],
  73. html`
  74. <div class="ml-2"></div>
  75. <div class="ml-4"></div>
  76. `
  77. )
  78. let input = css`
  79. @tailwind utilities;
  80. `
  81. let result = await run(input, config)
  82. let allContexts = Array.from(sharedState.contextMap.values())
  83. let context = allContexts[allContexts.length - 1]
  84. let ruleCacheSize1 = context.ruleCache.size
  85. expect(result.css).toMatchFormattedCss(css`
  86. .ml-2 {
  87. margin-left: 0.5rem !important;
  88. }
  89. .ml-4 {
  90. margin-left: 1rem !important;
  91. }
  92. `)
  93. await fs.promises.writeFile(
  94. config.content[0],
  95. html`
  96. <div class="ml-2"></div>
  97. <div class="ml-6"></div>
  98. `
  99. )
  100. result = await run(input, config)
  101. let ruleCacheSize2 = context.ruleCache.size
  102. expect(result.css).toMatchFormattedCss(css`
  103. .ml-2 {
  104. margin-left: 0.5rem !important;
  105. }
  106. .ml-4 {
  107. margin-left: 1rem !important;
  108. }
  109. .ml-6 {
  110. margin-left: 1.5rem !important;
  111. }
  112. `)
  113. // The rule cache was effectively doubling in size previously
  114. // because the rule cache was never de-duped
  115. // This ensures this behavior doesn't return
  116. expect(ruleCacheSize2 - ruleCacheSize1).toBeLessThan(10)
  117. })
  118. })