You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

903 lines
21 KiB

1 month ago
  1. 'use strict';
  2. const { test } = require('uvu');
  3. const assert = require('uvu/assert');
  4. const postcss = require('postcss');
  5. const reduceCalc = require('../index.js');
  6. const postcssOpts = { from: undefined };
  7. function testValue(fixture, expected, opts = {}) {
  8. fixture = `foo{bar:${fixture}}`;
  9. expected = `foo{bar:${expected}}`;
  10. return async () => {
  11. const result = await postcss(reduceCalc(opts)).process(
  12. fixture,
  13. postcssOpts
  14. );
  15. assert.is(result.css, expected);
  16. };
  17. }
  18. function testCss(fixture, expected, opts = {}) {
  19. return async () => {
  20. const result = await postcss(reduceCalc(opts)).process(
  21. fixture,
  22. postcssOpts
  23. );
  24. assert.is(result.css, expected);
  25. };
  26. }
  27. function testThrows(fixture, expected, warning, opts = {}) {
  28. fixture = `foo{bar:${fixture}}`;
  29. expected = `foo{bar:${expected}}`;
  30. return async () => {
  31. const result = await postcss(reduceCalc(opts)).process(
  32. fixture,
  33. postcssOpts
  34. );
  35. const warnings = result.warnings();
  36. assert.is(result.css, expected);
  37. assert.is(warnings[0].text, warning);
  38. };
  39. }
  40. test('should reduce simple calc (1)', testValue('calc(1px + 1px)', '2px'));
  41. test(
  42. 'should reduce simple calc (2)',
  43. testValue('calc(1px + 1px);baz:calc(2px+3px)', '2px;baz:5px')
  44. );
  45. test('should reduce simple calc (3)', testValue('calc(1rem * 1.5)', '1.5rem'));
  46. test('should reduce simple calc (4)', testValue('calc(3em - 1em)', '2em'));
  47. test('should reduce simple calc (5', testValue('calc(2ex / 2)', '1ex'));
  48. test(
  49. 'should reduce simple calc (6)',
  50. testValue('calc(50px - (20px - 30px))', '60px')
  51. );
  52. test(
  53. 'should reduce simple calc (7)',
  54. testValue('calc(100px - (100px - 100%))', '100%')
  55. );
  56. test(
  57. 'should reduce simple calc (8)',
  58. testValue('calc(100px + (100px - 100%))', 'calc(200px - 100%)')
  59. );
  60. test(
  61. 'should reduce additions and subtractions (1)',
  62. testValue('calc(100% - 10px + 20px)', 'calc(100% + 10px)')
  63. );
  64. test(
  65. 'should reduce additions and subtractions (2)',
  66. testValue('calc(100% + 10px - 20px)', 'calc(100% - 10px)')
  67. );
  68. test(
  69. 'should reduce additions and subtractions (3)',
  70. testValue('calc(1px - (2em + 3%))', 'calc(1px - 2em - 3%)')
  71. );
  72. test(
  73. 'should reduce additions and subtractions (4)',
  74. testValue('calc((100vw - 50em) / 2)', 'calc(50vw - 25em)')
  75. );
  76. test(
  77. 'should reduce additions and subtractions (5)',
  78. testValue('calc(10px - (100vw - 50em) / 2)', 'calc(10px - 50vw + 25em)')
  79. );
  80. test(
  81. 'should reduce additions and subtractions (6)',
  82. testValue('calc(1px - (2em + 4vh + 3%))', 'calc(1px - 2em - 4vh - 3%)')
  83. );
  84. test(
  85. 'should reduce additions and subtractions (7)',
  86. testValue(
  87. 'calc(0px - (24px - (var(--a) - var(--b)) / 2 + var(--c)))',
  88. 'calc(-24px + (var(--a) - var(--b))/2 - var(--c))'
  89. )
  90. );
  91. test(
  92. 'should reduce additions and subtractions (8)',
  93. testValue('calc(1px + (2em + (3vh + 4px)))', 'calc(5px + 2em + 3vh)')
  94. );
  95. test(
  96. 'should reduce additions and subtractions (9)',
  97. testValue('calc(1px - (2em + 4px - 6vh) / 2)', 'calc(-1px - 1em + 3vh)')
  98. );
  99. test(
  100. 'should reduce multiplication',
  101. testValue('calc(((var(--a) + 4px) * 2) * 2)', 'calc((var(--a) + 4px)*2*2)')
  102. );
  103. test(
  104. 'should reduce multiplication before reducing additions',
  105. testValue(
  106. 'calc(((var(--a) + 4px) * 2) * 2 + 4px)',
  107. 'calc((var(--a) + 4px)*2*2 + 4px)'
  108. )
  109. );
  110. test(
  111. 'should reduce division',
  112. testValue('calc(((var(--a) + 4px) / 2) / 2)', 'calc((var(--a) + 4px)/2/2)')
  113. );
  114. test(
  115. 'should reduce division before reducing additions',
  116. testValue(
  117. 'calc(((var(--a) + 4px) / 2) / 2 + 4px)',
  118. 'calc((var(--a) + 4px)/2/2 + 4px)'
  119. )
  120. );
  121. test(
  122. 'should ignore value surrounding calc function (1)',
  123. testValue('a calc(1px + 1px)', 'a 2px')
  124. );
  125. test(
  126. 'should ignore value surrounding calc function (2)',
  127. testValue('calc(1px + 1px) a', '2px a')
  128. );
  129. test(
  130. 'should ignore value surrounding calc function (3)',
  131. testValue('a calc(1px + 1px) b', 'a 2px b')
  132. );
  133. test(
  134. 'should ignore value surrounding calc function (4)',
  135. testValue('a calc(1px + 1px) b calc(1em + 2em) c', 'a 2px b 3em c')
  136. );
  137. test(
  138. 'should reduce nested calc',
  139. testValue('calc(100% - calc(50% + 25px))', 'calc(50% - 25px)')
  140. );
  141. test(
  142. 'should reduce vendor-prefixed nested calc',
  143. testValue(
  144. '-webkit-calc(100% - -webkit-calc(50% + 25px))',
  145. '-webkit-calc(50% - 25px)'
  146. )
  147. );
  148. test('should reduce uppercase calc (1)', testValue('CALC(1px + 1px)', '2px'));
  149. test(
  150. 'should reduce uppercase calc (2)',
  151. testValue('CALC(1px + CALC(2px / 2))', '2px')
  152. );
  153. test(
  154. 'should reduce uppercase calc (3)',
  155. testValue('-WEBKIT-CALC(1px + 1px)', '2px')
  156. );
  157. test(
  158. 'should reduce uppercase calc (4)',
  159. testValue('-WEBKIT-CALC(1px + -WEBKIT-CALC(2px / 2))', '2px')
  160. );
  161. test(
  162. 'should ignore calc with css variables (1)',
  163. testValue('calc(var(--mouseX) * 1px)', 'calc(var(--mouseX)*1px)')
  164. );
  165. test(
  166. 'should ignore calc with css variables (2)',
  167. testValue(
  168. 'calc(10px - (100px * var(--mouseX)))',
  169. 'calc(10px - 100px*var(--mouseX))'
  170. )
  171. );
  172. test(
  173. 'should ignore calc with css variables (3)',
  174. testValue(
  175. 'calc(10px - (100px + var(--mouseX)))',
  176. 'calc(-90px - var(--mouseX))'
  177. )
  178. );
  179. test(
  180. 'should ignore calc with css variables (4)',
  181. testValue(
  182. 'calc(10px - (100px / var(--mouseX)))',
  183. 'calc(10px - 100px/var(--mouseX))'
  184. )
  185. );
  186. test(
  187. 'should ignore calc with css variables (5)',
  188. testValue(
  189. 'calc(10px - (100px - var(--mouseX)))',
  190. 'calc(-90px + var(--mouseX))'
  191. )
  192. );
  193. test(
  194. 'should ignore calc with css variables (6)',
  195. testValue('calc(var(--popupHeight) / 2)', 'calc(var(--popupHeight)/2)')
  196. );
  197. test(
  198. 'should ignore calc with css variables (7)',
  199. testValue(
  200. 'calc(var(--popupHeight) / 2 + var(--popupWidth) / 2)',
  201. 'calc(var(--popupHeight)/2 + var(--popupWidth)/2)'
  202. )
  203. );
  204. test(
  205. 'should reduce calc with newline characters',
  206. testValue('calc(\n1rem \n* 2 \n* 1.5)', '3rem')
  207. );
  208. test(
  209. 'should preserve calc with incompatible units',
  210. testValue('calc(100% + 1px)', 'calc(100% + 1px)')
  211. );
  212. test(
  213. 'should parse fractions without leading zero',
  214. testValue('calc(2rem - .14285em)', 'calc(2rem - 0.14285em)')
  215. );
  216. test('should handle precision correctly (1)', testValue('calc(1/100)', '0.01'));
  217. test(
  218. 'should handle precision correctly (2)',
  219. testValue('calc(5/1000000)', '0.00001')
  220. );
  221. test(
  222. 'should handle precision correctly (3)',
  223. testValue('calc(5/1000000)', '0.000005', { precision: 6 })
  224. );
  225. test(
  226. 'should reduce browser-prefixed calc (1)',
  227. testValue('-webkit-calc(1px + 1px)', '2px')
  228. );
  229. test(
  230. 'should reduce browser-prefixed calc (2)',
  231. testValue('-moz-calc(1px + 1px)', '2px')
  232. );
  233. test(
  234. 'should discard zero values (#2) (1)',
  235. testValue('calc(100vw / 2 - 6px + 0px)', 'calc(50vw - 6px)')
  236. );
  237. test(
  238. 'should discard zero values (#2) (2)',
  239. testValue('calc(500px - 0px)', '500px')
  240. );
  241. test(
  242. 'should not perform addition on unitless values (#3)',
  243. testValue('calc(1px + 1)', 'calc(1px + 1)')
  244. );
  245. test(
  246. 'should reduce consecutive substractions (#24) (1)',
  247. testValue('calc(100% - 120px - 60px)', 'calc(100% - 180px)')
  248. );
  249. test(
  250. 'should reduce consecutive substractions (#24) (2)',
  251. testValue('calc(100% - 10px - 20px)', 'calc(100% - 30px)')
  252. );
  253. test(
  254. 'should reduce mixed units of time (postcss-calc#33)',
  255. testValue('calc(1s - 50ms)', '0.95s')
  256. );
  257. test(
  258. 'should correctly reduce calc with mixed units (cssnano#211)',
  259. testValue('calc(99.99% * 1/1 - 0rem)', '99.99%')
  260. );
  261. test(
  262. 'should apply optimization (cssnano#320)',
  263. testValue('calc(50% + (5em + 5%))', 'calc(55% + 5em)')
  264. );
  265. test(
  266. 'should reduce substraction from zero',
  267. testValue('calc( 0 - 10px)', '-10px')
  268. );
  269. test(
  270. 'should reduce subtracted expression from zero',
  271. testValue('calc( 0 - calc(1px + 1em) )', 'calc(-1px - 1em)')
  272. );
  273. test(
  274. 'should reduce substracted expression from zero (1)',
  275. testValue('calc( 0 - (100vw - 10px) / 2 )', 'calc(-50vw + 5px)')
  276. );
  277. test(
  278. 'should reduce substracted expression from zero (2)',
  279. testValue('calc( 0px - (100vw - 10px))', 'calc(10px - 100vw)')
  280. );
  281. test(
  282. 'should reduce substracted expression from zero (3)',
  283. testValue('calc( 0px - (100vw - 10px) * 2 )', 'calc(20px - 200vw)')
  284. );
  285. test(
  286. 'should reduce substracted expression from zero (4)',
  287. testValue('calc( 0px - (100vw + 10px))', 'calc(-10px - 100vw)')
  288. );
  289. test(
  290. 'should reduce substracted expression from zero (css-variable)',
  291. testValue(
  292. 'calc( 0px - (var(--foo, 4px) / 2))',
  293. 'calc(0px - var(--foo, 4px)/2)'
  294. )
  295. );
  296. test(
  297. 'should reduce nested expression',
  298. testValue('calc( (1em - calc( 10px + 1em)) / 2)', '-5px')
  299. );
  300. test(
  301. 'should skip constant function',
  302. testValue(
  303. 'calc(constant(safe-area-inset-left))',
  304. 'calc(constant(safe-area-inset-left))'
  305. )
  306. );
  307. test(
  308. 'should skip env function',
  309. testValue(
  310. 'calc(env(safe-area-inset-left))',
  311. 'calc(env(safe-area-inset-left))'
  312. )
  313. );
  314. test(
  315. 'should skip env function (#1)',
  316. testValue(
  317. 'calc(env(safe-area-inset-left, 50px 20px))',
  318. 'calc(env(safe-area-inset-left, 50px 20px))'
  319. )
  320. );
  321. test(
  322. 'should skip unknown function',
  323. testValue(
  324. 'calc(unknown(safe-area-inset-left))',
  325. 'calc(unknown(safe-area-inset-left))'
  326. )
  327. );
  328. test(
  329. 'should preserve the original declaration when `preserve` option is set to true',
  330. testCss('foo{bar:calc(1rem * 1.5)}', 'foo{bar:1.5rem;bar:calc(1rem * 1.5)}', {
  331. preserve: true,
  332. })
  333. );
  334. test(
  335. 'should not yield warnings when nothing is wrong',
  336. testValue('calc(500px - 0px)', '500px', { warnWhenCannotResolve: true })
  337. );
  338. test(
  339. 'should warn when calc expression cannot be reduced to a single value',
  340. testValue('calc(100% + 1px)', 'calc(100% + 1px)', {
  341. warnWhenCannotResolve: true,
  342. })
  343. );
  344. test(
  345. 'should reduce mixed units of time (#33)',
  346. testValue('calc(1s - 50ms)', '0.95s')
  347. );
  348. test(
  349. 'should not parse variables as calc expressions (#35)',
  350. testCss(
  351. 'foo:nth-child(2n + $var-calc){}',
  352. 'foo:nth-child(2n + $var-calc){}',
  353. { selectors: true }
  354. )
  355. );
  356. test(
  357. 'should apply algebraic reduction (cssnano#319)',
  358. testValue('calc((100px - 1em) + (-50px + 1em))', '50px')
  359. );
  360. test(
  361. 'should discard zero values (reduce-css-calc#2) (1)',
  362. testValue('calc(100vw / 2 - 6px + 0px)', 'calc(50vw - 6px)')
  363. );
  364. test(
  365. 'should discard zero values (reduce-css-calc#2) (2)',
  366. testValue('calc(500px - 0px)', '500px')
  367. );
  368. test(
  369. 'should not perform addition on unitless values (reduce-css-calc#3)',
  370. testValue('calc(1px + 1)', 'calc(1px + 1)')
  371. );
  372. test(
  373. 'should return the same and not thrown an exception for attribute selectors without a value',
  374. testCss('button[disabled]{}', 'button[disabled]{}', { selectors: true })
  375. );
  376. test(
  377. 'should ignore reducing custom property',
  378. testCss(
  379. ':root { --foo: calc(var(--bar) / 8); }',
  380. ':root { --foo: calc(var(--bar)/8); }'
  381. )
  382. );
  383. test(
  384. 'should ignore media queries',
  385. testCss(
  386. '@media (min-width:calc(10px+10px)){}',
  387. '@media (min-width:calc(10px+10px)){}'
  388. )
  389. );
  390. test(
  391. 'should reduce calc in media queries when `mediaQueries` option is set to true',
  392. testCss('@media (min-width:calc(10px+10px)){}', '@media (min-width:20px){}', {
  393. mediaQueries: true,
  394. })
  395. );
  396. test(
  397. 'should ignore selectors (1)',
  398. testCss('div[data-size="calc(3*3)"]{}', 'div[data-size="calc(3*3)"]{}')
  399. );
  400. test(
  401. 'should ignore selectors (2)',
  402. testCss('div:nth-child(2n + calc(3*3)){}', 'div:nth-child(2n + calc(3*3)){}')
  403. );
  404. test(
  405. 'should reduce calc in selectors when `selectors` option is set to true (1)',
  406. testCss('div[data-size="calc(3*3)"]{}', 'div[data-size="9"]{}', {
  407. selectors: true,
  408. })
  409. );
  410. test(
  411. 'should reduce calc in selectors when `selectors` option is set to true (2)',
  412. testCss('div:nth-child(2n + calc(3*3)){}', 'div:nth-child(2n + 9){}', {
  413. selectors: true,
  414. })
  415. );
  416. test(
  417. 'should not reduce 100% to 1 (reduce-css-calc#44)',
  418. testCss(
  419. '.@supports (width:calc(100% - constant(safe-area-inset-left))){.a{width:calc(100% - constant(safe-area-inset-left))}}',
  420. '.@supports (width:calc(100% - constant(safe-area-inset-left))){.a{width:calc(100% - constant(safe-area-inset-left))}}'
  421. )
  422. );
  423. test(
  424. 'should not break css variables that have "calc" in their names',
  425. testCss(
  426. 'a{transform: translateY(calc(-100% - var(--tooltip-calculated-offset)))}',
  427. 'a{transform: translateY(calc(-100% - var(--tooltip-calculated-offset)))}'
  428. )
  429. );
  430. test(
  431. 'should handle complex calculations (reduce-css-calc#45) (1)',
  432. testValue(
  433. 'calc(100% + (2 * 100px) - ((75.37% - 63.5px) - 900px))',
  434. 'calc(24.63% + 1163.5px)'
  435. )
  436. );
  437. test(
  438. 'should handle complex calculations (reduce-css-calc#45) (2)',
  439. testValue(
  440. 'calc(((((100% + (2 * 30px) + 63.5px) / 0.7537) - (100vw - 60px)) / 2) + 30px)',
  441. 'calc(66.33939% + 141.92915px - 50vw)'
  442. )
  443. );
  444. test(
  445. 'should handle advanced arithmetic (1)',
  446. testValue(
  447. 'calc(((75.37% - 63.5px) - 900px) + (2 * 100px))',
  448. 'calc(75.37% - 763.5px)'
  449. )
  450. );
  451. test(
  452. 'should handle advanced arithmetic (2)',
  453. testValue(
  454. 'calc((900px - (10% - 63.5px)) + (2 * 100px))',
  455. 'calc(1163.5px - 10%)'
  456. )
  457. );
  458. test(
  459. 'should handle nested calc statements (reduce-css-calc#49)',
  460. testValue('calc(calc(2.25rem + 2px) - 1px * 2)', '2.25rem')
  461. );
  462. test(
  463. 'should throw an exception when attempting to divide by zero',
  464. testThrows('calc(500px/0)', 'calc(500px/0)', 'Cannot divide by zero')
  465. );
  466. test(
  467. 'should throw an exception when attempting to divide by unit (#1)',
  468. testThrows(
  469. 'calc(500px/2px)',
  470. 'calc(500px/2px)',
  471. 'Cannot divide by "px", number expected'
  472. )
  473. );
  474. test(
  475. 'nested var (reduce-css-calc#50)',
  476. testValue(
  477. 'calc(var(--xxx, var(--yyy)) / 2)',
  478. 'calc(var(--xxx, var(--yyy))/2)'
  479. )
  480. );
  481. test(
  482. 'should not throw an exception when unknow function exist in calc',
  483. testValue(
  484. 'calc(unknown(#fff) - other-unknown(200px))',
  485. 'calc(unknown(#fff) - other-unknown(200px))'
  486. )
  487. );
  488. test(
  489. 'should not throw an exception when unknow function exist in calc (#1)',
  490. testValue(
  491. 'calc(unknown(#fff) * other-unknown(200px))',
  492. 'calc(unknown(#fff)*other-unknown(200px))'
  493. )
  494. );
  495. test(
  496. 'should not strip calc with single CSS custom variable',
  497. testValue('calc(var(--foo))', 'calc(var(--foo))')
  498. );
  499. test(
  500. 'should strip unnecessary calc with single CSS custom variable',
  501. testValue('calc(calc(var(--foo)))', 'calc(var(--foo))')
  502. );
  503. test(
  504. 'should not strip calc with single CSS custom variables and value',
  505. testValue('calc(var(--foo) + 10px)', 'calc(var(--foo) + 10px)')
  506. );
  507. test('should reduce calc (uppercase)', testValue('CALC(1PX + 1PX)', '2PX'));
  508. test(
  509. 'should reduce calc (uppercase) (#1)',
  510. testValue('CALC(VAR(--foo) + VAR(--bar))', 'CALC(VAR(--foo) + VAR(--bar))')
  511. );
  512. test(
  513. 'should reduce calc (uppercase) (#2)',
  514. testValue('CALC( (1EM - CALC( 10PX + 1EM)) / 2)', '-5PX')
  515. );
  516. test(
  517. 'should handle nested calc function (#1)',
  518. testValue(
  519. 'calc(calc(var(--foo) + var(--bar)) + var(--baz))',
  520. 'calc(var(--foo) + var(--bar) + var(--baz))'
  521. )
  522. );
  523. test(
  524. 'should handle nested calc function (#2)',
  525. testValue(
  526. 'calc(var(--foo) + calc(var(--bar) + var(--baz)))',
  527. 'calc(var(--foo) + var(--bar) + var(--baz))'
  528. )
  529. );
  530. test(
  531. 'should handle nested calc function (#3)',
  532. testValue(
  533. 'calc(calc(var(--foo) - var(--bar)) - var(--baz))',
  534. 'calc(var(--foo) - var(--bar) - var(--baz))'
  535. )
  536. );
  537. test(
  538. 'should handle nested calc function (#4)',
  539. testValue(
  540. 'calc(var(--foo) - calc(var(--bar) - var(--baz)))',
  541. 'calc(var(--foo) - var(--bar) + var(--baz))'
  542. )
  543. );
  544. test(
  545. 'should handle nested calc function (#5)',
  546. testValue(
  547. 'calc(calc(var(--foo) + var(--bar)) - var(--baz))',
  548. 'calc(var(--foo) + var(--bar) - var(--baz))'
  549. )
  550. );
  551. test(
  552. 'should handle nested calc function (#6)',
  553. testValue(
  554. 'calc(var(--foo) + calc(var(--bar) - var(--baz)))',
  555. 'calc(var(--foo) + var(--bar) - var(--baz))'
  556. )
  557. );
  558. test(
  559. 'should handle nested calc function (#7)',
  560. testValue(
  561. 'calc(calc(var(--foo) - var(--bar)) + var(--baz))',
  562. 'calc(var(--foo) - var(--bar) + var(--baz))'
  563. )
  564. );
  565. test(
  566. 'should handle nested calc function (#8)',
  567. testValue(
  568. 'calc(var(--foo) - calc(var(--bar) + var(--baz)))',
  569. 'calc(var(--foo) - var(--bar) - var(--baz))'
  570. )
  571. );
  572. test(
  573. 'should handle nested calc function (#9)',
  574. testValue(
  575. 'calc(calc(var(--foo) + var(--bar)) * var(--baz))',
  576. 'calc((var(--foo) + var(--bar))*var(--baz))'
  577. )
  578. );
  579. test(
  580. 'should handle nested calc function (#10)',
  581. testValue(
  582. 'calc(var(--foo) * calc(var(--bar) + var(--baz)))',
  583. 'calc(var(--foo)*(var(--bar) + var(--baz)))'
  584. )
  585. );
  586. test(
  587. 'should handle nested calc function (#11)',
  588. testValue(
  589. 'calc(calc(var(--foo) + var(--bar)) / var(--baz))',
  590. 'calc((var(--foo) + var(--bar))/var(--baz))'
  591. )
  592. );
  593. test(
  594. 'should handle nested calc function (#12)',
  595. testValue(
  596. 'calc(var(--foo) / calc(var(--bar) + var(--baz)))',
  597. 'calc(var(--foo)/(var(--bar) + var(--baz)))'
  598. )
  599. );
  600. test(
  601. 'should handle nested calc function (#13)',
  602. testValue(
  603. 'calc(100vh - 5rem - calc(10rem + 100px))',
  604. 'calc(100vh - 15rem - 100px)'
  605. )
  606. );
  607. test(
  608. 'should handle nested calc function (#14)',
  609. testValue('calc(100% - calc(10px + 2vw))', 'calc(100% - 10px - 2vw)')
  610. );
  611. test(
  612. 'should handle nested calc function (#15)',
  613. testValue('calc(100% - calc(10px - 2vw))', 'calc(100% - 10px + 2vw)')
  614. );
  615. test(
  616. 'should preserve division precedence',
  617. testValue(
  618. 'calc(100%/(var(--aspect-ratio)))',
  619. 'calc(100%/(var(--aspect-ratio)))'
  620. )
  621. );
  622. test(
  623. 'should preserve division precedence (2)',
  624. testValue(
  625. `calc(
  626. (var(--fluid-screen) - ((var(--fluid-min-width) / 16) * 1rem)) /
  627. ((var(--fluid-max-width) / 16) - (var(--fluid-min-width) / 16))
  628. )`,
  629. 'calc((var(--fluid-screen) - ((var(--fluid-min-width)/16)*1rem))/(var(--fluid-max-width)/16 - var(--fluid-min-width)/16))'
  630. )
  631. );
  632. test(
  633. 'should preserve division precedence (3)',
  634. testValue('calc(1/(10/var(--dot-size)))', 'calc(1/(10/var(--dot-size)))')
  635. );
  636. test(
  637. 'should correctly preserve parentheses',
  638. testValue(
  639. 'calc(1/((var(--a) - var(--b))/16))',
  640. 'calc(1/(var(--a) - var(--b))/16)'
  641. )
  642. );
  643. test('precision for calc', testValue('calc(100% / 3 * 3)', '100%'));
  644. test(
  645. 'precision for nested calc',
  646. testValue('calc(calc(100% / 3) * 3)', '100%')
  647. );
  648. test('plus sign', testValue('calc(+100px + +100px)', '200px'));
  649. test('plus sign (#1)', testValue('calc(+100px - +100px)', '0px'));
  650. test('plus sign (#2)', testValue('calc(200px * +1)', '200px'));
  651. test('plus sign (#3)', testValue('calc(200px / +1)', '200px'));
  652. test('minus sign', testValue('calc(-100px + -100px)', '-200px'));
  653. test('minus sign (#2)', testValue('calc(-100px - -100px)', '0px'));
  654. test('minus sign (#3)', testValue('calc(200px * -1)', '-200px'));
  655. test('minus sign (#4)', testValue('calc(200px / -1)', '-200px'));
  656. test('whitespace', testValue('calc( 100px + 100px )', '200px'));
  657. test('whitespace (#1)', testValue('calc(\t100px\t+\t100px\t)', '200px'));
  658. test('whitespace (#2)', testValue('calc(\n100px\n+\n100px\n)', '200px'));
  659. test(
  660. 'whitespace (#4)',
  661. testValue('calc(\r\n100px\r\n+\r\n100px\r\n)', '200px')
  662. );
  663. test(
  664. 'comments',
  665. testValue('calc(/*test*/100px/*test*/ + /*test*/100px/*test*/)', '200px')
  666. );
  667. test(
  668. 'comments (#1)',
  669. testValue('calc(/*test*/100px/*test*/*/*test*/2/*test*/)', '200px')
  670. );
  671. test(
  672. 'comments nested',
  673. testValue(
  674. 'calc(/*test*/100px + calc(/*test*/100px/*test*/ + /*test*/100px/*test*/))',
  675. '300px'
  676. )
  677. );
  678. test('exponent composed', testValue('calc(1.1e+1px + 1.1e+1px)', '22px'));
  679. test('exponent composed (#1)', testValue('calc(10e+1px + 10e+1px)', '200px'));
  680. test(
  681. 'exponent composed (#2)',
  682. testValue('calc(1.1e+10px + 1.1e+10px)', '22000000000px')
  683. );
  684. test('exponent composed (#3)', testValue('calc(9e+1 * 1px)', '90px'));
  685. test('exponent composed (#4)', testValue('calc(9e+1% + 10%)', '100%'));
  686. test(
  687. 'exponent composed (uppercase)',
  688. testValue('calc(1.1E+1px + 1.1E+1px)', '22px')
  689. );
  690. test('convert units', testValue('calc(1cm + 1px)', '1.02646cm'));
  691. test('convert units (#1)', testValue('calc(1px + 1cm)', '38.79528px'));
  692. test('convert units (#2)', testValue('calc(10Q + 10Q)', '20Q'));
  693. test('convert units (#3)', testValue('calc(100.9q + 10px)', '111.48333q'));
  694. test('convert units (#4)', testValue('calc(10px + 100.9q)', '105.33858px'));
  695. test('convert units (#5)', testValue('calc(10cm + 1px)', '10.02646cm'));
  696. test('convert units (#6)', testValue('calc(10mm + 1px)', '10.26458mm'));
  697. test('convert units (#7)', testValue('calc(10px + 1q)', '10.94488px'));
  698. test('convert units (#8)', testValue('calc(10cm + 1q)', '10.025cm'));
  699. test('convert units (#9)', testValue('calc(10mm + 1q)', '10.25mm'));
  700. test('convert units (#10)', testValue('calc(10in + 1q)', '10.00984in'));
  701. test('convert units (#11)', testValue('calc(10pt + 1q)', '10.70866pt'));
  702. test('convert units (#12)', testValue('calc(10pc + 1q)', '10.05906pc'));
  703. test('convert units (#13)', testValue('calc(1q + 10px)', '11.58333q'));
  704. test('convert units (#14)', testValue('calc(1q + 10cm)', '401q'));
  705. test('convert units (#15)', testValue('calc(1q + 10mm)', '41q'));
  706. test('convert units (#16)', testValue('calc(1q + 10in)', '1017q'));
  707. test('convert units (#17)', testValue('calc(1q + 10pt)', '15.11111q'));
  708. test('convert units (#18)', testValue('calc(1q + 10pc)', '170.33333q'));
  709. test(
  710. 'unknown units',
  711. testValue('calc(1unknown + 2unknown)', 'calc(1unknown + 2unknown)')
  712. );
  713. test(
  714. 'unknown units with known',
  715. testValue('calc(1unknown + 2px)', 'calc(1unknown + 2px)')
  716. );
  717. test(
  718. 'unknown units with known (#1)',
  719. testValue('calc(1px + 2unknown)', 'calc(1px + 2unknown)')
  720. );
  721. test(
  722. 'error with parsing',
  723. testThrows(
  724. 'calc(10pc + unknown)',
  725. 'calc(10pc + unknown)',
  726. 'Lexical error on line 1: Unrecognized text.\n\n Erroneous area:\n1: 10pc + unknown\n^.........^'
  727. )
  728. );
  729. test.run();