customConfig.test.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. import fs from 'fs'
  2. import path from 'path'
  3. import inTempDirectory from '../jest/runInTempDirectory'
  4. import { run, html, css, javascript } from './util/run'
  5. const defaultConfigFile = 'tailwind.config.js'
  6. const cjsConfigFile = 'tailwind.config.cjs'
  7. test('it uses the values from the custom config file', () => {
  8. let config = require(path.resolve(`${__dirname}/fixtures/custom-config.js`))
  9. return run('@tailwind utilities', config).then((result) => {
  10. expect(result.css).toMatchFormattedCss(css`
  11. @media (min-width: 400px) {
  12. .mobile\:font-bold {
  13. font-weight: 700;
  14. }
  15. }
  16. `)
  17. })
  18. })
  19. test('custom config can be passed as an object', () => {
  20. let config = {
  21. content: [{ raw: html`<div class="mobile:font-bold"></div>` }],
  22. theme: {
  23. screens: {
  24. mobile: '400px',
  25. },
  26. },
  27. }
  28. return run('@tailwind utilities', config).then((result) => {
  29. expect(result.css).toMatchFormattedCss(css`
  30. @media (min-width: 400px) {
  31. .mobile\:font-bold {
  32. font-weight: 700;
  33. }
  34. }
  35. `)
  36. })
  37. })
  38. test('custom config path can be passed using `config` property in an object', () => {
  39. let config = {
  40. config: path.resolve(`${__dirname}/fixtures/custom-config.js`),
  41. }
  42. return run('@tailwind utilities', config).then((result) => {
  43. expect(result.css).toMatchFormattedCss(css`
  44. @media (min-width: 400px) {
  45. .mobile\:font-bold {
  46. font-weight: 700;
  47. }
  48. }
  49. `)
  50. })
  51. })
  52. test('custom config can be passed under the `config` property', () => {
  53. let config = {
  54. config: {
  55. content: [{ raw: html`<div class="mobile:font-bold"></div>` }],
  56. theme: {
  57. screens: {
  58. mobile: '400px',
  59. },
  60. },
  61. },
  62. }
  63. return run('@tailwind utilities', config).then((result) => {
  64. expect(result.css).toMatchFormattedCss(css`
  65. @media (min-width: 400px) {
  66. .mobile\:font-bold {
  67. font-weight: 700;
  68. }
  69. }
  70. `)
  71. })
  72. })
  73. test('tailwind.config.cjs is picked up by default', () => {
  74. return inTempDirectory(() => {
  75. fs.writeFileSync(
  76. path.resolve(cjsConfigFile),
  77. javascript`module.exports = {
  78. content: [{ raw: '<div class="mobile:font-bold"></div>' }],
  79. theme: {
  80. screens: {
  81. mobile: '400px',
  82. },
  83. },
  84. }`
  85. )
  86. return run('@tailwind utilities').then((result) => {
  87. expect(result.css).toMatchFormattedCss(css`
  88. @media (min-width: 400px) {
  89. .mobile\:font-bold {
  90. font-weight: 700;
  91. }
  92. }
  93. `)
  94. })
  95. })
  96. })
  97. test('tailwind.config.js is picked up by default', () => {
  98. return inTempDirectory(() => {
  99. fs.writeFileSync(
  100. path.resolve(defaultConfigFile),
  101. javascript`module.exports = {
  102. content: [{ raw: '<div class="mobile:font-bold"></div>' }],
  103. theme: {
  104. screens: {
  105. mobile: '400px',
  106. },
  107. },
  108. }`
  109. )
  110. return run('@tailwind utilities').then((result) => {
  111. expect(result.css).toMatchFormattedCss(css`
  112. @media (min-width: 400px) {
  113. .mobile\:font-bold {
  114. font-weight: 700;
  115. }
  116. }
  117. `)
  118. })
  119. })
  120. })
  121. test('tailwind.config.cjs is picked up by default when passing an empty object', () => {
  122. return inTempDirectory(() => {
  123. fs.writeFileSync(
  124. path.resolve(cjsConfigFile),
  125. javascript`module.exports = {
  126. content: [{ raw: '<div class="mobile:font-bold"></div>' }],
  127. theme: {
  128. screens: {
  129. mobile: '400px',
  130. },
  131. },
  132. }`
  133. )
  134. return run('@tailwind utilities', {}).then((result) => {
  135. expect(result.css).toMatchFormattedCss(css`
  136. @media (min-width: 400px) {
  137. .mobile\:font-bold {
  138. font-weight: 700;
  139. }
  140. }
  141. `)
  142. })
  143. })
  144. })
  145. test('tailwind.config.js is picked up by default when passing an empty object', () => {
  146. return inTempDirectory(() => {
  147. fs.writeFileSync(
  148. path.resolve(defaultConfigFile),
  149. javascript`module.exports = {
  150. content: [{ raw: '<div class="mobile:font-bold"></div>' }],
  151. theme: {
  152. screens: {
  153. mobile: '400px',
  154. },
  155. },
  156. }`
  157. )
  158. return run('@tailwind utilities', {}).then((result) => {
  159. expect(result.css).toMatchFormattedCss(css`
  160. @media (min-width: 400px) {
  161. .mobile\:font-bold {
  162. font-weight: 700;
  163. }
  164. }
  165. `)
  166. })
  167. })
  168. })
  169. test('the default config can be overridden using the presets key', () => {
  170. let config = {
  171. content: [{ raw: html`<div class="min-h-primary min-h-secondary min-h-0"></div>` }],
  172. presets: [
  173. {
  174. theme: {
  175. extend: { minHeight: { secondary: '24px' } },
  176. },
  177. },
  178. ],
  179. theme: {
  180. extend: { minHeight: { primary: '48px' } },
  181. },
  182. }
  183. return run('@tailwind utilities', config).then((result) => {
  184. expect(result.css).toMatchFormattedCss(css`
  185. .min-h-0 {
  186. min-height: 0;
  187. }
  188. .min-h-primary {
  189. min-height: 48px;
  190. }
  191. .min-h-secondary {
  192. min-height: 24px;
  193. }
  194. `)
  195. })
  196. })
  197. test('presets can be functions', () => {
  198. let config = {
  199. content: [{ raw: html`<div class="min-h-primary min-h-secondary min-h-0"></div>` }],
  200. presets: [
  201. () => ({
  202. theme: {
  203. extend: { minHeight: { secondary: '24px' } },
  204. },
  205. }),
  206. ],
  207. theme: {
  208. extend: { minHeight: { primary: '48px' } },
  209. },
  210. }
  211. return run('@tailwind utilities', config).then((result) => {
  212. expect(result.css).toMatchFormattedCss(css`
  213. .min-h-0 {
  214. min-height: 0;
  215. }
  216. .min-h-primary {
  217. min-height: 48px;
  218. }
  219. .min-h-secondary {
  220. min-height: 24px;
  221. }
  222. `)
  223. })
  224. })
  225. test('the default config can be removed by using an empty presets key in a preset', () => {
  226. let config = {
  227. content: [{ raw: html`<div class="min-h-primary min-h-secondary min-h-0"></div>` }],
  228. presets: [
  229. {
  230. presets: [],
  231. theme: {
  232. extend: { minHeight: { secondary: '24px' } },
  233. },
  234. },
  235. ],
  236. theme: {
  237. extend: { minHeight: { primary: '48px' } },
  238. },
  239. }
  240. return run('@tailwind utilities', config).then((result) => {
  241. expect(result.css).toMatchFormattedCss(css`
  242. .min-h-primary {
  243. min-height: 48px;
  244. }
  245. .min-h-secondary {
  246. min-height: 24px;
  247. }
  248. `)
  249. })
  250. })
  251. test('presets can have their own presets', () => {
  252. let config = {
  253. content: [{ raw: html`<div class="bg-red bg-transparent bg-black bg-white"></div>` }],
  254. presets: [
  255. {
  256. presets: [],
  257. theme: {
  258. colors: { red: '#dd0000' },
  259. },
  260. },
  261. {
  262. presets: [
  263. {
  264. presets: [],
  265. theme: {
  266. colors: {
  267. transparent: 'transparent',
  268. red: '#ff0000',
  269. },
  270. },
  271. },
  272. ],
  273. theme: {
  274. extend: {
  275. colors: {
  276. black: 'black',
  277. red: '#ee0000',
  278. },
  279. backgroundColor: (theme) => theme('colors'),
  280. },
  281. },
  282. corePlugins: ['backgroundColor'],
  283. },
  284. ],
  285. theme: {
  286. extend: { colors: { white: 'white' } },
  287. },
  288. }
  289. return run('@tailwind utilities', config).then((result) => {
  290. expect(result.css).toMatchFormattedCss(css`
  291. .bg-black {
  292. background-color: #000;
  293. }
  294. .bg-red {
  295. background-color: #e00;
  296. }
  297. .bg-transparent {
  298. background-color: #0000;
  299. }
  300. .bg-white {
  301. background-color: #fff;
  302. }
  303. `)
  304. })
  305. })
  306. test('function presets can be mixed with object presets', () => {
  307. let config = {
  308. content: [{ raw: html`<div class="bg-red bg-transparent bg-black bg-white"></div>` }],
  309. presets: [
  310. () => ({
  311. presets: [],
  312. theme: {
  313. colors: { red: '#dd0000' },
  314. },
  315. }),
  316. {
  317. presets: [
  318. () => ({
  319. presets: [],
  320. theme: {
  321. colors: {
  322. transparent: 'transparent',
  323. red: '#ff0000',
  324. },
  325. },
  326. }),
  327. ],
  328. theme: {
  329. extend: {
  330. colors: {
  331. black: 'black',
  332. red: '#ee0000',
  333. },
  334. backgroundColor: (theme) => theme('colors'),
  335. },
  336. },
  337. corePlugins: ['backgroundColor'],
  338. },
  339. ],
  340. theme: {
  341. extend: { colors: { white: 'white' } },
  342. },
  343. }
  344. return run('@tailwind utilities', config).then((result) => {
  345. expect(result.css).toMatchFormattedCss(css`
  346. .bg-black {
  347. background-color: #000;
  348. }
  349. .bg-red {
  350. background-color: #e00;
  351. }
  352. .bg-transparent {
  353. background-color: #0000;
  354. }
  355. .bg-white {
  356. background-color: #fff;
  357. }
  358. `)
  359. })
  360. })