pxtorpx-spec.js 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. // Jasmine unit tests
  2. // To run tests, run these commands from the project root:
  3. // 1. `npm install -g jasmine-node`
  4. // 2. `jasmine-node spec`
  5. /* global describe, it, expect */
  6. "use strict";
  7. var postcss = require("postcss");
  8. var pxtorpx = require("..");
  9. var basicCSS = ".rule { font-size: 15px }";
  10. describe("pxtorpx", function() {
  11. it("should work on the readme example", function() {
  12. var input =
  13. "h1 { margin: 0 0 20px; font-size: 32px; line-height: 1.2; letter-spacing: 1px; }";
  14. var output =
  15. "h1 { margin: 0 0 40rpx; font-size: 64rpx; line-height: 1.2; letter-spacing: 2rpx; }";
  16. var processed = postcss(pxtorpx()).process(input).css;
  17. expect(processed).toBe(output);
  18. });
  19. it("should replace the px unit with rpx", function() {
  20. var processed = postcss(pxtorpx()).process(basicCSS).css;
  21. var expected = ".rule { font-size: 30rpx }";
  22. expect(processed).toBe(expected);
  23. });
  24. it("should ignore non px properties", function() {
  25. var expected = ".rule { font-size: 2em }";
  26. var processed = postcss(pxtorpx()).process(expected).css;
  27. expect(processed).toBe(expected);
  28. });
  29. it("should ignore px in custom property names", function() {
  30. var rules =
  31. ":root { --rpx-14px: 14px; } .rule { font-size: var(--rpx-14px); }";
  32. var expected =
  33. ":root { --rpx-14px: 28rpx; } .rule { font-size: var(--rpx-14px); }";
  34. var processed = postcss(pxtorpx()).process(rules).css;
  35. expect(processed).toBe(expected);
  36. });
  37. it("should handle < 1 values and values without a leading 0", function() {
  38. var rules = ".rule { margin: 0.5rpx .5px -0.2px -.2em }";
  39. var expected = ".rule { margin: 0.5rpx 1rpx -0.4rpx -.2em }";
  40. var options = {};
  41. var processed = postcss(pxtorpx(options)).process(rules).css;
  42. expect(processed).toBe(expected);
  43. });
  44. it("should not add properties that already exist", function() {
  45. var expected = ".rule { font-size: 16px; font-size: 32rpx; }";
  46. var processed = postcss(pxtorpx()).process(expected).css;
  47. expect(processed).toBe(expected);
  48. });
  49. it("should remain unitless if 0", function() {
  50. var expected = ".rule { font-size: 0px; font-size: 0; }";
  51. var processed = postcss(pxtorpx()).process(expected).css;
  52. expect(processed).toBe(expected);
  53. });
  54. });
  55. describe("value parsing", function() {
  56. it("should not replace values in double quotes or single quotes", function() {
  57. var options = {};
  58. var rules =
  59. ".rule { content: '16px'; font-family: \"16px\"; font-size: 16px; }";
  60. var expected =
  61. ".rule { content: '16px'; font-family: \"16px\"; font-size: 32rpx; }";
  62. var processed = postcss(pxtorpx(options)).process(rules).css;
  63. expect(processed).toBe(expected);
  64. });
  65. it("should not replace values in `url()`", function() {
  66. var options = {};
  67. var rules = ".rule { background: url(16px.jpg); font-size: 16px; }";
  68. var expected = ".rule { background: url(16px.jpg); font-size: 32rpx; }";
  69. var processed = postcss(pxtorpx(options)).process(rules).css;
  70. expect(processed).toBe(expected);
  71. });
  72. it("should not replace values with an uppercase P or X", function() {
  73. var options = {};
  74. var rules =
  75. ".rule { margin: 12px calc(100% - 14PX); height: calc(100% - 20px); font-size: 12Px; line-height: 16px; }";
  76. var expected =
  77. ".rule { margin: 24rpx calc(100% - 14PX); height: calc(100% - 40rpx); font-size: 12Px; line-height: 32rpx; }";
  78. var processed = postcss(pxtorpx(options)).process(rules).css;
  79. expect(processed).toBe(expected);
  80. });
  81. });
  82. describe("unit", function() {
  83. it("should replace with specific unit", function() {
  84. var expected = ".rule { font-size: 30rem }";
  85. var options = {
  86. unit: "rem"
  87. };
  88. var processed = postcss(pxtorpx(options)).process(basicCSS).css;
  89. expect(processed).toBe(expected);
  90. });
  91. });
  92. describe("unitPrecision", function() {
  93. it("should replace using a decimal of 2 places", function() {
  94. var css = ".rule { margin: 0.24px }";
  95. var expected = ".rule { margin: 0.5rpx }";
  96. var options = {
  97. unitPrecision: 1
  98. };
  99. var processed = postcss(pxtorpx(options)).process(css).css;
  100. expect(processed).toBe(expected);
  101. });
  102. });
  103. describe("propBlackList", function() {
  104. it("should not replace properties in the prop list", function() {
  105. var css =
  106. ".rule { font-size: 16px; margin: 16px; margin-left: 5px; padding: 5px; padding-right: 16px }";
  107. var expected =
  108. ".rule { font-size: 16px; margin: 16px; margin-left: 10rpx; padding: 10rpx; padding-right: 16px }";
  109. var options = {
  110. propBlackList: ["*font*", "margin*", "!margin-left", "*-right", "pad"]
  111. };
  112. var processed = postcss(pxtorpx(options)).process(css).css;
  113. expect(processed).toBe(expected);
  114. });
  115. it("should not only replace properties in the prop list with wildcard", function() {
  116. var css =
  117. ".rule { font-size: 16px; margin: 16px; margin-left: 5px; padding: 5px; padding-right: 16px }";
  118. var expected =
  119. ".rule { font-size: 32rpx; margin: 16px; margin-left: 10rpx; padding: 10rpx; padding-right: 32rpx }";
  120. var options = {
  121. propBlackList: ["*", "!margin-left", "!*padding*", "!font*"]
  122. };
  123. var processed = postcss(pxtorpx(options)).process(css).css;
  124. expect(processed).toBe(expected);
  125. });
  126. it("should replace all properties when white list is empty", function() {
  127. var rules = ".rule { margin: 16px; font-size: 15px }";
  128. var expected = ".rule { margin: 32rpx; font-size: 30rpx }";
  129. var options = {
  130. propBlackList: []
  131. };
  132. var processed = postcss(pxtorpx(options)).process(rules).css;
  133. expect(processed).toBe(expected);
  134. });
  135. });
  136. describe("selectorBlackList", function() {
  137. it("should ignore selectors in the selector black list", function() {
  138. var rules = ".rule { font-size: 15px } .rule2 { font-size: 15px }";
  139. var expected = ".rule { font-size: 30rpx } .rule2 { font-size: 15px }";
  140. var options = {
  141. selectorBlackList: [".rule2"]
  142. };
  143. var processed = postcss(pxtorpx(options)).process(rules).css;
  144. expect(processed).toBe(expected);
  145. });
  146. it("should ignore every selector with `body$`", function() {
  147. var rules =
  148. "body { font-size: 16px; } .class-body$ { font-size: 16px; } .simple-class { font-size: 16px; }";
  149. var expected =
  150. "body { font-size: 32rpx; } .class-body$ { font-size: 16px; } .simple-class { font-size: 32rpx; }";
  151. var options = {
  152. selectorBlackList: ["body$"]
  153. };
  154. var processed = postcss(pxtorpx(options)).process(rules).css;
  155. expect(processed).toBe(expected);
  156. });
  157. it("should only ignore exactly `body`", function() {
  158. var rules =
  159. "body { font-size: 16px; } .class-body { font-size: 16px; } .simple-class { font-size: 16px; }";
  160. var expected =
  161. "body { font-size: 16px; } .class-body { font-size: 32rpx; } .simple-class { font-size: 32rpx; }";
  162. var options = {
  163. selectorBlackList: [/^body$/]
  164. };
  165. var processed = postcss(pxtorpx(options)).process(rules).css;
  166. expect(processed).toBe(expected);
  167. });
  168. });
  169. describe("replace", function() {
  170. it("should leave fallback pixel unit with root em value", function() {
  171. var options = {
  172. replace: false
  173. };
  174. var processed = postcss(pxtorpx(options)).process(basicCSS).css;
  175. var expected = ".rule { font-size: 15px; font-size: 30rpx }";
  176. expect(processed).toBe(expected);
  177. });
  178. });
  179. describe("mediaQuery", function() {
  180. it("should replace px in media queries", function() {
  181. var options = {
  182. mediaQuery: true
  183. };
  184. var processed = postcss(pxtorpx(options)).process(
  185. "@media (min-width: 500px) { .rule { font-size: 16px } }"
  186. ).css;
  187. var expected = "@media (min-width: 1000rpx) { .rule { font-size: 32rpx } }";
  188. expect(processed).toBe(expected);
  189. });
  190. it("should not replace px in media queries", function() {
  191. var options = {
  192. mediaQuery: false
  193. };
  194. var processed = postcss(pxtorpx(options)).process(
  195. "@media (min-width: 500px) { .rule { font-size: 16px } }"
  196. ).css;
  197. var expected = "@media (min-width: 500px) { .rule { font-size: 32rpx } }";
  198. expect(processed).toBe(expected);
  199. });
  200. });
  201. describe("minPixelValue", function() {
  202. it("should not replace values below minPixelValue", function() {
  203. var options = {
  204. minPixelValue: 2
  205. };
  206. var rules =
  207. ".rule { border: 1px solid #000; font-size: 16px; margin: 1px 10px; }";
  208. var expected =
  209. ".rule { border: 1px solid #000; font-size: 32rpx; margin: 1px 20rpx; }";
  210. var processed = postcss(pxtorpx(options)).process(rules).css;
  211. expect(processed).toBe(expected);
  212. });
  213. });
  214. describe("transform", function() {
  215. it("should use custom transform function to transform unit", function() {
  216. var options = {
  217. transform: pixels => pixels
  218. };
  219. var rules =
  220. ".rule { border: 1px solid #000; font-size: 16px; margin: 1px 10px; }";
  221. var expected =
  222. ".rule { border: 1rpx solid #000; font-size: 16rpx; margin: 1rpx 10rpx; }";
  223. var processed = postcss(pxtorpx(options)).process(rules).css;
  224. expect(processed).toBe(expected);
  225. });
  226. });
  227. describe("exclude", function() {
  228. it("should ignore file path with exclude RegEx", function() {
  229. var options = {
  230. exclude: /exclude/i
  231. };
  232. var processed = postcss(pxtorpx(options)).process(basicCSS, {
  233. from: "exclude/path"
  234. }).css;
  235. expect(processed).toBe(basicCSS);
  236. });
  237. it("should not ignore file path with exclude String", function() {
  238. var options = {
  239. exclude: "exclude"
  240. };
  241. var processed = postcss(pxtorpx(options)).process(basicCSS, {
  242. from: "exclude/path"
  243. }).css;
  244. expect(processed).toBe(basicCSS);
  245. });
  246. it("should not ignore file path with exclude function", function() {
  247. var options = {
  248. exclude: function(file) {
  249. return file.indexOf("exclude") !== -1;
  250. }
  251. };
  252. var processed = postcss(pxtorpx(options)).process(basicCSS, {
  253. from: "exclude/path"
  254. }).css;
  255. expect(processed).toBe(basicCSS);
  256. });
  257. });