🚀 Big News:Socket Has Acquired Secure Annex.Learn More
Socket
Book a DemoSign in
Socket

cssstats

Package Overview
Dependencies
Maintainers
2
Versions
39
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cssstats - npm Package Compare versions

Comparing version
3.4.1
to
3.5.0
+15
test/keyframes-test.js
const test = require('ava')
const { getStatsForFixture } = require('./util')
test('does not return keyframes stops in selectors', (t) => {
const result = getStatsForFixture('keyframes')
t.deepEqual(result.selectors.values, ['.a', '.b'])
})
test('returns proper stats in and after a keyframe', (t) => {
const result = getStatsForFixture('keyframes')
t.deepEqual(result.declarations.properties.color.length, 5)
})
const test = require('ava')
const { getStatsForFixture } = require('./util')
test('does not include media queries when set to false', (t) => {
const result = getStatsForFixture('small', { mediaQueries: false })
t.falsy(result.mediaQueries.contents)
})
const fs = require('fs')
const path = require('path')
const test = require('ava')
const postcss = require('postcss')
const cssstats = require('..')
const { fixture } = require('./util')
test('works as a postcss plugin', async (t) => {
const result = await postcss().use(cssstats()).process(fixture('small'))
const stats = result.messages[0].stats
t.snapshot(stats)
})
const test = require('ava')
const { getStatsForFixture } = require('./util')
test('returns proper file sizes for the small fixture', (t) => {
const result = getStatsForFixture('small')
t.is(result.size, 885)
t.is(result.gzipSize, 367)
t.is(result.humanizedGzipSize, '367B')
})
test('returns proper file sizes for basscss fixture', (t) => {
const result = getStatsForFixture('basscss')
t.is(result.size, 18858)
t.is(result.gzipSize, 3546)
t.is(result.humanizedGzipSize, '3KB')
})
const test = require('ava')
const { getStatsForFixture } = require('./util')
const FIXTURES = ['basscss', 'font-awesome', 'font-shorthand', 'stackoverflow']
FIXTURES.forEach((fixture) => {
test(`matches snapshot for ${fixture}`, (t) => {
const result = getStatsForFixture(fixture)
t.snapshot(result)
})
})
# Snapshot report for `packages/cssstats/test/plugin-test.js`
The actual snapshot is saved in `plugin-test.js.snap`.
Generated by [AVA](https://avajs.dev).
## works as a postcss plugin
> Snapshot 1
{
declarations: {
getAllFontFamilies: Function {},
getAllFontSizes: Function {},
getPropertyResets: Function {},
getPropertyValueCount: Function {},
getUniquePropertyCount: Function {},
getVendorPrefixed: Function {},
properties: {
'-ms-border-radius': [
'0',
],
'-ms-transform': [
'translateY(-20px) translate3d(0, 0, 0)',
'translateY(0) translate3d(0, 0, 0)',
],
'-webkit-transform': [
'translateY(-20px) translate3d(0, 0, 0)',
'translateY(0) translate3d(0, 0, 0)',
],
'background-color': [
'hotpink',
],
'border-bottom': [
'none',
],
color: [
'red',
'red',
'tomato',
],
content: [
'\'hello\'',
],
font: [
'1.5em Georgia',
],
margin: [
'10px',
'0px 0',
],
'margin-bottom': [
'0px',
],
opacity: [
'.8',
'0',
'1',
],
padding: [
'5px',
'0',
],
transform: [
'translateY(-20px) translate3d(0, 0, 0)',
'translateY(0) translate3d(0, 0, 0)',
],
},
total: 22,
unique: 21,
},
gzipSize: 367,
humanizedGzipSize: '367B',
humanizedSize: '885B',
mediaQueries: {
contents: [
{
declarations: {
getAllFontFamilies: Function {},
getAllFontSizes: Function {},
getPropertyResets: Function {},
getPropertyValueCount: Function {},
getUniquePropertyCount: Function {},
getVendorPrefixed: Function {},
properties: {
'-ms-border-radius': [
'0',
],
'background-color': [
'hotpink',
],
color: [
'tomato',
],
},
total: 3,
unique: 3,
},
rules: {
selectorByRuleSizes: [
{
declarations: 3,
selector: '.sm-tomato',
},
],
size: {
average: 3,
graph: [
3,
],
max: 3,
},
total: 1,
},
selectors: {
class: 1,
getRepeatedValues: Function {},
getSortedSpecificity: Function {},
getSpecificityGraph: Function {},
getSpecificityValues: Function {},
id: 0,
pseudoClass: 0,
pseudoElement: 0,
specificity: {
average: 10,
max: 10,
},
total: 1,
type: 0,
values: [
'.sm-tomato',
],
},
value: '(min-width: 30em)',
},
],
total: 1,
unique: 1,
values: [
'(min-width: 30em)',
],
},
rules: {
selectorByRuleSizes: [
{
declarations: 4,
selector: '100%',
},
{
declarations: 4,
selector: '0%',
},
{
declarations: 3,
selector: '.sm-tomato',
},
{
declarations: 2,
selector: '.box',
},
{
declarations: 2,
selector: '.sm-tomato:first-child:last-child',
},
{
declarations: 1,
selector: '.georgia',
},
{
declarations: 1,
selector: 'header',
},
{
declarations: 1,
selector: '.box:last-child',
},
{
declarations: 1,
selector: '.box:first-child',
},
{
declarations: 1,
selector: '.sm-tomato::after',
},
{
declarations: 1,
selector: '.red',
},
{
declarations: 1,
selector: '.red, #foo',
},
],
size: {
average: 1.8333333333333333,
graph: [
1,
1,
3,
1,
2,
2,
1,
1,
4,
4,
1,
1,
],
max: 4,
},
total: 12,
},
selectors: {
class: 9,
getRepeatedValues: Function {},
getSortedSpecificity: Function {},
getSpecificityGraph: Function {},
getSpecificityValues: Function {},
id: 1,
pseudoClass: 3,
pseudoElement: 1,
specificity: {
average: 21.09090909090909,
max: 100,
},
total: 11,
type: 1,
values: [
'.red',
'#foo',
'.red',
'.sm-tomato',
'.sm-tomato::after',
'.sm-tomato:first-child:last-child',
'.box',
'.box:first-child',
'.box:last-child',
'header',
'.georgia',
],
},
size: 885,
toJSON: Function {},
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

const test = require('ava')
const { getStatsForFixture } = require('./util')
test('generates a specificity graph', (t) => {
const result = getStatsForFixture('small').selectors.getSpecificityGraph()
t.is(result.length, 11)
})
test('returns specificity values', (t) => {
const result = getStatsForFixture('small').selectors.getSpecificityValues()
t.deepEqual(result, [
{
selector: '.red',
specificity: 10,
},
{
selector: '#foo',
specificity: 100,
},
{
selector: '.red',
specificity: 10,
},
{
selector: '.sm-tomato',
specificity: 10,
},
{
selector: '.sm-tomato::after',
specificity: 11,
},
{
selector: '.sm-tomato:first-child:last-child',
specificity: 30,
},
{
selector: '.box',
specificity: 10,
},
{
selector: '.box:first-child',
specificity: 20,
},
{
selector: '.box:last-child',
specificity: 20,
},
{
selector: 'header',
specificity: 1,
},
{
selector: '.georgia',
specificity: 10,
},
])
})
test('returns sorted specificity values', (t) => {
const result = getStatsForFixture('small')
.selectors.getSortedSpecificity()
.slice(0, 4)
t.deepEqual(result, [
{
selector: '#foo',
specificity: 100,
},
{
selector: '.sm-tomato:first-child:last-child',
specificity: 30,
},
{
selector: '.box:first-child',
specificity: 20,
},
{
selector: '.box:last-child',
specificity: 20,
},
])
})
test('returns repeated selectors', (t) => {
const result = getStatsForFixture('small').selectors.getRepeatedValues()
t.deepEqual(result, ['.red'])
})
const fs = require('fs')
const path = require('path')
const test = require('ava')
const postcss = require('postcss')
const cssstats = require('..')
function fixture(name) {
return fs
.readFileSync(path.join(__dirname, 'fixtures/' + name + '.css'), 'utf8')
.toString()
.trim()
}
module.exports.fixture = fixture
module.exports.getStatsForFixture = (fixtureName, options = {}) => {
return cssstats(fixture(fixtureName), options)
}
+7
-5

@@ -6,2 +6,3 @@ var _ = require('lodash')

var gzipSize = require('gzip-size')
var size = require('./lib/size')

@@ -13,3 +14,3 @@ var rules = require('./lib/rules')

module.exports = function(src, opts) {
module.exports = function (src, opts) {
opts = opts || {}

@@ -24,3 +25,3 @@ opts = _.defaults(opts, {

propertyResets: false,
vendorPrefixedProperties: false
vendorPrefixedProperties: false,
})

@@ -47,7 +48,7 @@

plugin: 'postcss-cssstats',
stats: stats
stats: stats,
})
}
stats.toJSON = function() {
stats.toJSON = function () {
// Remove methods when using JSON.stringify

@@ -72,3 +73,4 @@ delete stats.selectors.getSpecificityGraph

// Default behavior
var root = postcss().process(src, { parser: safeParser }).root
var root = postcss([]).process(src, { parser: safeParser, from: undefined })
.root
var result = parse(root, {})

@@ -75,0 +77,0 @@ return result

{
"name": "cssstats",
"version": "3.4.1",
"version": "3.5.0",
"description": "High-level stats for stylesheets",

@@ -8,3 +8,3 @@ "main": "index.js",

"license": "MIT",
"repository": "cssstats/cssstats-core",
"repository": "cssstats/cssstats",
"keywords": [

@@ -17,28 +17,21 @@ "CSS",

"dependencies": {
"bytes": "^3.0.0",
"css-selector-tokenizer": "^0.7.0",
"css-shorthand-expand": "^1.1.0",
"gzip-size": "^4.1.0",
"has-class-selector": "^3.3.1",
"has-element-selector": "^3.3.1",
"has-id-selector": "^3.3.1",
"has-pseudo-class": "^3.3.1",
"has-pseudo-element": "^3.3.1",
"bytes": "^3.1.0",
"css-selector-tokenizer": "^0.7.3",
"css-shorthand-expand": "^1.2.0",
"gzip-size": "^5.1.1",
"has-class-selector": "^3.5.0",
"has-element-selector": "^3.5.0",
"has-id-selector": "^3.5.0",
"has-pseudo-class": "^3.5.0",
"has-pseudo-element": "^3.5.0",
"is-blank": "^2.1.0",
"is-css-shorthand": "^1.0.1",
"is-present": "^1.0.0",
"is-vendor-prefixed": "^3.3.1",
"lodash": "^4.17.5",
"postcss": "^6.0.21",
"postcss-safe-parser": "^3.0.1",
"specificity": "^0.3.2"
"is-vendor-prefixed": "^3.5.0",
"lodash": "^4.17.20",
"postcss": "^8.1.4",
"postcss-safe-parser": "^5.0.2",
"specificity": "^0.4.1"
},
"devDependencies": {
"get-css": "^3.4.1",
"mocha": "^5.0.5"
},
"scripts": {
"test": "rm -rf test/results && mkdir test/results && mocha test"
},
"gitHead": "24602286cb10123ec6286404c89af5105763733d"
"gitHead": "dddf9c82cec12c909947f89d551fa86a74e90dba"
}

@@ -1,2 +0,2 @@

# cssstats [![Build Status](https://travis-ci.org/cssstats/core.svg?branch=master)](https://travis-ci.org/cssstats/core)
# cssstats

@@ -38,4 +38,4 @@ Parses stylesheets and returns an object with statistics.

.process(css)
.then(function(result) {
result.messages.forEach(function(message) {
.then(function (result) {
result.messages.forEach(function (message) {
console.log(message)

@@ -42,0 +42,0 @@ })

@@ -78,3 +78,3 @@ {

"selectors": {
"total": 13,
"total": 11,
"type": 1,

@@ -95,4 +95,2 @@ "class": 9,

".box:last-child",
"0%",
"100%",
"header",

@@ -103,3 +101,3 @@ ".georgia"

"max": 100,
"average": 18
"average": 21.09090909090909
}

@@ -106,0 +104,0 @@ },

var fs = require('fs')
var assert = require('assert')
var postcss = require('postcss')
var cssstats = require('..')
describe('css-statistics', function() {
var stats
var options = {
importantDeclarations: true
}
before(function() {
stats = cssstats(fixture('small'), options)
})
describe('PostCSS plugin', function() {
it('should be handled correctly', function(done) {
postcss()
.use(cssstats(options))
.process(fixture('small'))
.then(function(result) {
var pluginStats = result.messages[0].stats
assert.deepEqual(pluginStats.selectors, stats.selectors)
done()
})
})
})
describe('size stats', function() {
it('should calculate the correct file size', function() {
assert.equal(stats.size, 885)
})
it('should calculate the correct gzipped file size', function() {
assert.equal(stats.gzipSize, 367)
})
})
describe('rules', function() {
it('should count the total number of rules', function() {
assert.equal(stats.rules.total, 12)
})
it('should correctly calculate max rule size', function() {
assert.equal(stats.rules.size.max, 4)
})
it('should correctly calculate average rule size', function() {
assert.equal(stats.rules.size.average, 1.8333333333333333)
})
it('should return a rule size graph', function() {
assert.deepEqual(stats.rules.size.graph, [
1,
1,
3,
1,
2,
2,
1,
1,
4,
4,
1,
1
])
})
it('should return a selectorByRuleSizes array', function() {
assert.deepEqual(stats.rules.selectorByRuleSizes, [
{ selector: '100%', declarations: 4 },
{ selector: '0%', declarations: 4 },
{ selector: '.sm-tomato', declarations: 3 },
{ selector: '.box', declarations: 2 },
{ selector: '.sm-tomato:first-child:last-child', declarations: 2 },
{ selector: '.georgia', declarations: 1 },
{ selector: 'header', declarations: 1 },
{ selector: '.box:last-child', declarations: 1 },
{ selector: '.box:first-child', declarations: 1 },
{ selector: '.sm-tomato::after', declarations: 1 },
{ selector: '.red', declarations: 1 },
{ selector: '.red, #foo', declarations: 1 }
])
})
})
describe('selectors', function() {
it('should correctly count total selectors', function() {
assert.equal(stats.selectors.total, 13)
})
it('should correctly count the number of id selectors', function() {
assert.equal(stats.selectors.id, 1)
})
it('should correctly count the number of type selectors', function() {
assert.equal(stats.selectors.type, 1)
})
it('should correctly count the number of class selectors', function() {
assert.equal(stats.selectors.class, 9)
})
it('should correctly count the number of pseudo class selectors', function() {
assert.equal(stats.selectors.pseudoClass, 3)
})
it('should correctly count the number of pseudo element selectors', function() {
assert.equal(stats.selectors.pseudoElement, 1)
})
it('should return an array of selectors', function() {
assert.equal(stats.selectors.values.length > 0, true)
})
it('should correctly calculate max specificity', function() {
assert.equal(stats.selectors.specificity.max, 100)
})
it('should correctly calculate average specificity', function() {
assert.equal(stats.selectors.specificity.average, 18)
})
})
describe('declarations', function() {
it('should correctly count total declarations', function() {
assert.equal(stats.declarations.total, 22)
})
it('should correctly count unique declarations', function() {
assert.equal(stats.declarations.unique, 21)
})
it('should correctly count important values', function() {
assert.equal(stats.declarations.important.length, 2)
})
it('should return a properties object', function() {
assert.equal(Object.keys(stats.declarations.properties).length > 0, true)
})
})
describe('keyframes', function() {
var keyframeStats
before(function() {
keyframeStats = cssstats(fixture('keyframes'))
})
it('should correctly get statistics for CSS in, and after, a keyframe', function() {
assert.equal(keyframeStats.declarations.properties.color.length, 5)
})
it('should not include @keyframes stops in the selectors list', function() {
assert.deepEqual(keyframeStats.selectors.values, ['.a', '.b'])
})
})
describe('selector methods', function() {
it('should generate a specificity graph', function() {
assert.equal(stats.selectors.getSpecificityGraph().length > 0, true)
})
it('should return specificity values for each selector in order', function() {
assert.deepEqual(stats.selectors.getSpecificityValues(), [
{ selector: '.red', specificity: 10 },
{ selector: '#foo', specificity: 100 },
{ selector: '.red', specificity: 10 },
{ selector: '.sm-tomato', specificity: 10 },
{ selector: '.sm-tomato::after', specificity: 11 },
{ selector: '.sm-tomato:first-child:last-child', specificity: 30 },
{ selector: '.box', specificity: 10 },
{ selector: '.box:first-child', specificity: 20 },
{ selector: '.box:last-child', specificity: 20 },
{ selector: '0%', specificity: 1 },
{ selector: '100%', specificity: 1 },
{ selector: 'header', specificity: 1 },
{ selector: '.georgia', specificity: 10 }
])
})
it('should return a sorted specificity array', function() {
assert.deepEqual(stats.selectors.getSortedSpecificity(), [
{ selector: '#foo', specificity: 100 },
{ selector: '.sm-tomato:first-child:last-child', specificity: 30 },
{ selector: '.box:first-child', specificity: 20 },
{ selector: '.box:last-child', specificity: 20 },
{ selector: '.sm-tomato::after', specificity: 11 },
{ selector: '.box', specificity: 10 },
{ selector: '.sm-tomato', specificity: 10 },
{ selector: '.red', specificity: 10 },
{ selector: '.red', specificity: 10 },
{ selector: '.georgia', specificity: 10 },
{ selector: '0%', specificity: 1 },
{ selector: '100%', specificity: 1 },
{ selector: 'header', specificity: 1 }
])
})
it('should return repeated selectors', function() {
assert.deepEqual(stats.selectors.getRepeatedValues(), ['.red'])
})
})
describe('declaration methods', function() {
it('should correctly count the number of declarations that reset properties', function() {
assert.deepEqual(stats.declarations.getPropertyResets(), {
margin: 1,
padding: 1,
'margin-bottom': 1
})
})
it('should correctly count the number of unique colors', function() {
assert.equal(stats.declarations.getUniquePropertyCount('color'), 2)
})
it('should correctly count the number of color: red', function() {
assert.equal(stats.declarations.getPropertyValueCount('color', 'red'), 2)
})
it('should get count vendor prefixes', function() {
assert.equal(stats.declarations.getVendorPrefixed().length, 5)
})
it('should get all font sizes', function() {
assert.equal(stats.declarations.getAllFontSizes().length, 1)
})
it('should get all font families', function() {
assert.equal(stats.declarations.getAllFontFamilies().length, 1)
})
})
it('should be able to parse css and produce stats', function(done) {
;[
'basscss',
'small',
'font-awesome',
'gridio',
'gridio-national-light'
].forEach(function(stylesheet) {
renderJson(stylesheet)
})
done()
})
})
describe('cssstats no media queries', function() {
var stats
before(function() {
stats = cssstats(fixture('small'), { mediaQueries: false })
})
it('should not contain media query contents', function() {
assert.equal(stats.mediaQueries.contents, null)
})
})
function fixture(name) {
return fs
.readFileSync('test/fixtures/' + name + '.css', 'utf8')
.toString()
.trim()
}
function renderJson(filename) {
var css = fixture(filename)
var obj = cssstats(css)
fs.writeFileSync(
'./test/results/' + filename + '.json',
JSON.stringify(obj, null, 2)
)
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display