postcss-rem-to-rem-multiplier
Version:
multiply the rem (root em) units with a multiplier using PostCSS. Based on postcss-rem-to-pixel.
303 lines (248 loc) • 12.5 kB
JavaScript
// Jasmine unit tests
// To run tests, run these commands from the project root:
// 1. `npm install -g jasmine-node`
// 2. `jasmine-node spec`
/* global describe, it, expect */
;
var postcss = require('postcss');
var remToremMultiplier = require('..');
var basicCSS = '.rule { font-size: 0.9375rem }';
var filterPropList = require('../lib/filter-prop-list');
describe('remToremMultiplier', function () {
it('should work on the readme example', function () {
var input = 'h1 { margin: 0 0 20px; font-size: 2rem; line-height: 1.2; letter-spacing: 0.0625rem; }';
var output = 'h1 { margin: 0 0 20px; font-size: 1.25rem; line-height: 1.2; letter-spacing: 0.03906rem; }';
var processed = postcss(remToremMultiplier()).process(input).css;
expect(processed).toBe(output);
});
it('should replace the rem unit with px', function () {
var processed = postcss(remToremMultiplier()).process(basicCSS).css;
var expected = '.rule { font-size: 0.58594rem }';
expect(processed).toBe(expected);
});
it('should ignore non rem properties', function () {
var expected = '.rule { font-size: 2em }';
var processed = postcss(remToremMultiplier()).process(expected).css;
expect(processed).toBe(expected);
});
it('should handle < 1 values and values without a leading 0', function () {
var rules = '.rule { margin: 0.5px .03125rem -0.0125rem -.2em }';
var expected = '.rule { margin: 0.5px 0.01953rem -0.00781rem -.2em }';
var options = {
propList: ['margin']
};
var processed = postcss(remToremMultiplier(options)).process(rules).css;
expect(processed).toBe(expected);
});
it('should remain unitless if 0', function () {
var input = '.rule { font-size: 0rem; font-size: 0; }';
var expected = '.rule { font-size: 0; font-size: 0; }';
var processed = postcss(remToremMultiplier()).process(input).css;
expect(processed).toBe(expected);
});
});
describe('value parsing', function () {
it('should not replace values in double quotes or single quotes', function () {
var options = {
propList: ['*']
};
var rules = '.rule { content: \'1rem\'; font-family: "1rem"; font-size: 1rem; }';
var expected = '.rule { content: \'1rem\'; font-family: "1rem"; font-size: 0.625rem; }';
var processed = postcss(remToremMultiplier(options)).process(rules).css;
expect(processed).toBe(expected);
});
it('should not replace values in `url()`', function () {
var options = {
propList: ['*']
};
var rules = '.rule { background: url(1rem.jpg); font-size: 1rem; }';
var expected = '.rule { background: url(1rem.jpg); font-size: 0.625rem; }';
var processed = postcss(remToremMultiplier(options)).process(rules).css;
expect(processed).toBe(expected);
});
it('should not replace values with an uppercase R or REM', function () {
var options = {
propList: ['*']
};
var rules = '.rule { margin: 0.75rem calc(100% - 14REM); height: calc(100% - 1.25rem); font-size: 12Rem; line-height: 1rem; }';
var expected = '.rule { margin: 0.46875rem calc(100% - 14REM); height: calc(100% - 0.78125rem); font-size: 12Rem; line-height: 0.625rem; }';
var processed = postcss(remToremMultiplier(options)).process(rules).css;
expect(processed).toBe(expected);
});
});
describe('multiplier', function () {
it('should replace using a root value of 10', function () {
var expected = '.rule { font-size: 9.375rem }';
var options = {
multiplier: 10
};
var processed = postcss(remToremMultiplier(options)).process(basicCSS).css;
expect(processed).toBe(expected);
});
});
describe('unitPrecision', function () {
it('should replace using a decimal of 2 places', function () {
var rules = '.rule { font-size: 0.534375rem }';
var expected = '.rule { font-size: 0.53rem }';
var options = {
unitPrecision: 2,
multiplier: 1
};
var processed = postcss(remToremMultiplier(options)).process(rules).css;
expect(processed).toBe(expected);
});
});
describe('propList', function () {
it('should only replace properties in the prop list', function () {
var rules = '.rule { font-size: 1rem; margin: 1rem; margin-left: 0.5rem; padding: 0.5rem; padding-right: 1rem }';
var expected = '.rule { font-size: 0.625rem; margin: 0.625rem; margin-left: 0.5rem; padding: 0.5rem; padding-right: 0.625rem }';
var options = {
propList: ['*font*', 'margin*', '!margin-left', '*-right', 'pad']
};
var processed = postcss(remToremMultiplier(options)).process(rules).css;
expect(processed).toBe(expected);
});
it('should only replace properties in the prop list with wildcard', function () {
var rules = '.rule { font-size: 1rem; margin: 1rem; margin-left: 0.5rem; padding: 0.5rem; padding-right: 1rem }';
var expected = '.rule { font-size: 1rem; margin: 0.625rem; margin-left: 0.5rem; padding: 0.5rem; padding-right: 1rem }';
var options = {
propList: ['*', '!margin-left', '!*padding*', '!font*']
};
var processed = postcss(remToremMultiplier(options)).process(rules).css;
expect(processed).toBe(expected);
});
it('should replace all properties when white list is wildcard', function () {
var rules = '.rule { margin: 1rem; font-size: 0.9375rem }';
var expected = '.rule { margin: 0.625rem; font-size: 0.58594rem }';
var options = {
propList: ['*']
};
var processed = postcss(remToremMultiplier(options)).process(rules).css;
expect(processed).toBe(expected);
});
});
describe('selectorBlackList', function () {
it('should ignore selectors in the selector black list', function () {
var rules = '.rule { font-size: 0.9375rem } .rule2 { font-size: 15rem }';
var expected = '.rule { font-size: 0.58594rem } .rule2 { font-size: 15rem }';
var options = {
selectorBlackList: ['.rule2']
};
var processed = postcss(remToremMultiplier(options)).process(rules).css;
expect(processed).toBe(expected);
});
it('should ignore every selector with `body$`', function () {
var rules = 'body { font-size: 1rem; } .class-body$ { font-size: 16rem; } .simple-class { font-size: 1rem; }';
var expected = 'body { font-size: 0.625rem; } .class-body$ { font-size: 16rem; } .simple-class { font-size: 0.625rem; }';
var options = {
selectorBlackList: ['body$']
};
var processed = postcss(remToremMultiplier(options)).process(rules).css;
expect(processed).toBe(expected);
});
it('should only ignore exactly `body`', function () {
var rules = 'body { font-size: 16rem; } .class-body { font-size: 1rem; } .simple-class { font-size: 1rem; }';
var expected = 'body { font-size: 16rem; } .class-body { font-size: 0.625rem; } .simple-class { font-size: 0.625rem; }';
var options = {
selectorBlackList: [/^body$/]
};
var processed = postcss(remToremMultiplier(options)).process(rules).css;
expect(processed).toBe(expected);
});
});
describe('mediaQuery', function () {
it('should replace rem in media queries', function () {
var rules = '@media (min-width: 31.25rem) { .rule { font-size: 1rem } }';
var expected = '@media (min-width: 19.53125rem) { .rule { font-size: 0.625rem } }';
var options = {
mediaQuery: true
};
var processed = postcss(remToremMultiplier(options)).process(rules).css;
expect(processed).toBe(expected);
});
});
describe('minRemValue', function () {
it('should not replace values below minRemValue', function () {
var rules = '.rule { border: 0.0625rem solid #000; font-size: 1rem; margin: 0.0625rem 0.625rem; }';
var expected = '.rule { border: 0.03906rem solid #000; font-size: 0.625rem; margin: 0.03906rem 0.39063rem; }';
var options = {
propList: ['*'],
minRemValue: 0.5
};
var processed = postcss(remToremMultiplier(options)).process(rules).css;
expect(processed).toBe(expected);
});
});
describe('filter-prop-list', function () {
it('should find "exact" matches from propList', function () {
var propList = ['font-size', 'margin', '!padding', '*border*', '*', '*y', '!*font*'];
var expected = 'font-size,margin';
expect(filterPropList.exact(propList).join()).toBe(expected);
});
it('should find "contain" matches from propList and reduce to string', function () {
var propList = ['font-size', '*margin*', '!padding', '*border*', '*', '*y', '!*font*'];
var expected = 'margin,border';
expect(filterPropList.contain(propList).join()).toBe(expected);
});
it('should find "start" matches from propList and reduce to string', function () {
var propList = ['font-size', '*margin*', '!padding', 'border*', '*', '*y', '!*font*'];
var expected = 'border';
expect(filterPropList.startWith(propList).join()).toBe(expected);
});
it('should find "end" matches from propList and reduce to string', function () {
var propList = ['font-size', '*margin*', '!padding', 'border*', '*', '*y', '!*font*'];
var expected = 'y';
expect(filterPropList.endWith(propList).join()).toBe(expected);
});
it('should find "not" matches from propList and reduce to string', function () {
var propList = ['font-size', '*margin*', '!padding', 'border*', '*', '*y', '!*font*'];
var expected = 'padding';
expect(filterPropList.notExact(propList).join()).toBe(expected);
});
it('should find "not contain" matches from propList and reduce to string', function () {
var propList = ['font-size', '*margin*', '!padding', '!border*', '*', '*y', '!*font*'];
var expected = 'font';
expect(filterPropList.notContain(propList).join()).toBe(expected);
});
it('should find "not start" matches from propList and reduce to string', function () {
var propList = ['font-size', '*margin*', '!padding', '!border*', '*', '*y', '!*font*'];
var expected = 'border';
expect(filterPropList.notStartWith(propList).join()).toBe(expected);
});
it('should find "not end" matches from propList and reduce to string', function () {
var propList = ['font-size', '*margin*', '!padding', '!border*', '*', '!*y', '!*font*'];
var expected = 'y';
expect(filterPropList.notEndWith(propList).join()).toBe(expected);
});
});
describe('multiplierCssVarName', function () {
it('should not replace values in double quotes or single quotes', function () {
var options = {
multiplier: 0.625,
multiplierCssVarName: '--r2rMulti'
};
var rules = '.rule { font-size: 1rem; }';
var expected = '.rule { font-size: calc(1rem * var(--r2rMulti)); }';
var processed = postcss(remToremMultiplier(options)).process(rules).css;
expect(processed).toBe(expected);
});
it('should not replace values in `url()`', function () {
var options = {
multiplier: 0.625,
multiplierCssVarName: '--r2rMulti'
};
var rules = '.rule { background: url(1rem.jpg); font-size: 1rem; }';
var expected = '.rule { background: url(1rem.jpg); font-size: calc(1rem * var(--r2rMulti)); }';
var processed = postcss(remToremMultiplier(options)).process(rules).css;
expect(processed).toBe(expected);
});
it('should not replace values with an uppercase R or REM', function () {
var options = {
propList: ['*']
};
var rules = '.rule { margin: 0.75rem calc(100% - 14REM); height: calc(100% - 1.25rem); font-size: 12Rem; line-height: 1rem; }';
var expected = '.rule { margin: 0.46875rem calc(100% - 14REM); height: calc(100% - 0.78125rem); font-size: 12Rem; line-height: 0.625rem; }';
var processed = postcss(remToremMultiplier(options)).process(rules).css;
expect(processed).toBe(expected);
});
});