compileStyle.spec.ts 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. import { parse } from '../src/parse'
  2. import { compileStyle, compileStyleAsync } from '../src/compileStyle'
  3. test('preprocess less', () => {
  4. const style = parse({
  5. source:
  6. '<style lang="less">\n' +
  7. '@red: rgb(255, 0, 0);\n' +
  8. '.color { color: @red; }\n' +
  9. '</style>\n',
  10. filename: 'example.vue',
  11. sourceMap: true
  12. }).styles[0]
  13. const result = compileStyle({
  14. id: 'v-scope-xxx',
  15. filename: 'example.vue',
  16. source: style.content,
  17. map: style.map,
  18. scoped: false,
  19. preprocessLang: style.lang
  20. })
  21. expect(result.errors.length).toBe(0)
  22. expect(result.code).toEqual(expect.stringContaining('color: #ff0000;'))
  23. expect(result.map).toBeTruthy()
  24. })
  25. test('preprocess scss', () => {
  26. const style = parse({
  27. source:
  28. '<style lang="scss">\n' +
  29. '$red: red;\n' +
  30. '.color { color: $red; }\n' +
  31. '</style>\n',
  32. filename: 'example.vue',
  33. sourceMap: true
  34. }).styles[0]
  35. const result = compileStyle({
  36. id: 'v-scope-xxx',
  37. filename: 'example.vue',
  38. source: style.content,
  39. map: style.map,
  40. scoped: false,
  41. preprocessLang: style.lang
  42. })
  43. expect(result.errors.length).toBe(0)
  44. expect(result.code).toMatch('color: red;')
  45. expect(result.map).toBeTruthy()
  46. })
  47. test('preprocess sass', () => {
  48. const style = parse({
  49. source:
  50. '<style lang="sass">\n' +
  51. '$red: red\n' +
  52. '.color\n' +
  53. ' color: $red\n' +
  54. '</style>\n',
  55. filename: 'example.vue',
  56. sourceMap: true
  57. }).styles[0]
  58. const result = compileStyle({
  59. id: 'v-scope-xxx',
  60. filename: 'example.vue',
  61. source: style.content,
  62. map: style.map,
  63. scoped: false,
  64. preprocessLang: style.lang
  65. })
  66. expect(result.errors.length).toBe(0)
  67. expect(result.code).toMatch('color: red;')
  68. expect(result.map).toBeTruthy()
  69. })
  70. test('preprocess stylus', () => {
  71. const style = parse({
  72. source:
  73. '<style lang="styl">\n' +
  74. 'red-color = rgb(255, 0, 0);\n' +
  75. '.color\n' +
  76. ' color: red-color\n' +
  77. '</style>\n',
  78. filename: 'example.vue',
  79. sourceMap: true
  80. }).styles[0]
  81. const result = compileStyle({
  82. id: 'v-scope-xxx',
  83. filename: 'example.vue',
  84. source: style.content,
  85. map: style.map,
  86. scoped: false,
  87. preprocessLang: style.lang
  88. })
  89. expect(result.errors.length).toBe(0)
  90. expect(result.code).toEqual(expect.stringContaining('color: #f00;'))
  91. expect(result.map).toBeTruthy()
  92. })
  93. test('custom postcss plugin', () => {
  94. const spy = vi.fn()
  95. compileStyle({
  96. id: 'v-scope-xxx',
  97. filename: 'example.vue',
  98. source: '.foo { color: red }',
  99. scoped: false,
  100. postcssPlugins: [require('postcss').plugin('test-plugin', () => spy)()]
  101. })
  102. expect(spy).toHaveBeenCalled()
  103. })
  104. test('custom postcss options', () => {
  105. const result = compileStyle({
  106. id: 'v-scope-xxx',
  107. filename: 'example.vue',
  108. source: '.foo { color: red }',
  109. scoped: false,
  110. postcssOptions: { random: 'foo' }
  111. })
  112. expect((result.rawResult as any).opts.random).toBe('foo')
  113. })
  114. test('async postcss plugin in sync mode', () => {
  115. const result = compileStyle({
  116. id: 'v-scope-xxx',
  117. filename: 'example.vue',
  118. source: '.foo { color: red }',
  119. scoped: false,
  120. postcssPlugins: [
  121. require('postcss').plugin(
  122. 'test-plugin',
  123. () => async (result: any) => result
  124. )
  125. ]
  126. })
  127. expect(result.errors).toHaveLength(1)
  128. })
  129. test('async postcss plugin', async () => {
  130. const promise = compileStyleAsync({
  131. id: 'v-scope-xxx',
  132. filename: 'example.vue',
  133. source: '.foo { color: red }',
  134. scoped: false,
  135. postcssPlugins: [
  136. require('postcss').plugin(
  137. 'test-plugin',
  138. () => async (result: any) => result
  139. )
  140. ]
  141. })
  142. expect(promise instanceof Promise).toBe(true)
  143. const result = await promise
  144. expect(result.errors).toHaveLength(0)
  145. expect(result.code).toEqual(expect.stringContaining('color: red'))
  146. })
  147. test('media query', () => {
  148. const result = compileStyle({
  149. id: 'v-scope-xxx',
  150. scoped: true,
  151. filename: 'example.vue',
  152. source: `
  153. @media print {
  154. .foo {
  155. color: #000;
  156. }
  157. }`
  158. })
  159. expect(result.errors).toHaveLength(0)
  160. expect(result.code).toContain(
  161. '@media print {\n.foo[v-scope-xxx] {\n color: #000;\n}\n}'
  162. )
  163. })
  164. test('supports query', () => {
  165. const result = compileStyle({
  166. id: 'v-scope-xxx',
  167. scoped: true,
  168. filename: 'example.vue',
  169. source: `
  170. @supports ( color: #000 ) {
  171. .foo {
  172. color: #000;
  173. }
  174. }`
  175. })
  176. expect(result.errors).toHaveLength(0)
  177. expect(result.code).toContain(
  178. '@supports ( color: #000 ) {\n.foo[v-scope-xxx] {\n color: #000;\n}\n}'
  179. )
  180. })