Skip to content

Commit

Permalink
Merge 4c31578 into 768cb44
Browse files Browse the repository at this point in the history
  • Loading branch information
bartveneman committed Apr 22, 2019
2 parents 768cb44 + 4c31578 commit 5cb55de
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 33 deletions.
3 changes: 1 addition & 2 deletions src/analyzer/index.js
Expand Up @@ -17,9 +17,8 @@ module.exports = async rawCss => {
const stylesheets = require('./stylesheets')({
rawCss,
atrules,
rules,
rules: css.rules,
selectors,
declarations,
properties,
values
})
Expand Down
31 changes: 24 additions & 7 deletions src/analyzer/stylesheets/cohesion.js
@@ -1,13 +1,30 @@
module.exports = (rules, declarations) => {
const average = ((rules, declarations) => {
if (declarations.total === 0) {
return 0
module.exports = rules => {
const totalRules = rules.length
const totalDeclarations =
totalRules === 0
? 0
: rules.reduce((acc, curr) => acc + curr.declarations.length, 0)
const rulesSortedByDeclarationCount = rules.sort(
(a, b) => b.declarations.length - a.declarations.length
)

if (totalRules === 0 || totalDeclarations === 0) {
return {
average: 0,
min: {
count: 0,
value: null
}
}
}

return declarations.total / rules.total
})(rules, declarations)
const [ruleWithMostDeclarations] = rulesSortedByDeclarationCount

return {
average
average: totalDeclarations / totalRules,
min: {
count: ruleWithMostDeclarations.declarations.length,
value: ruleWithMostDeclarations
}
}
}
12 changes: 2 additions & 10 deletions src/analyzer/stylesheets/index.js
@@ -1,15 +1,7 @@
module.exports = ({
rawCss,
atrules,
rules,
selectors,
declarations,
properties,
values
}) => {
module.exports = ({rawCss, atrules, rules, selectors, properties, values}) => {
const filesize = require('./size.js')(rawCss)
const simplicity = require('./simplicity.js')(rules, selectors)
const cohesion = require('./cohesion.js')(rules, declarations)
const cohesion = require('./cohesion.js')(rules)
const browserhacks = require('./browserhacks.js')(
atrules,
selectors,
Expand Down
2 changes: 1 addition & 1 deletion src/analyzer/stylesheets/simplicity.js
Expand Up @@ -3,5 +3,5 @@ module.exports = (rules, selectors) => {
return 0
}

return rules.total / selectors.total
return rules.length / selectors.total
}
8 changes: 5 additions & 3 deletions test/analyzer/index.js
@@ -1,7 +1,7 @@
const test = require('ava')
const analyzer = require('../..')

test('Breaks with invalid CSS', async t => {
test('it breaks with invalid CSS', async t => {
const cssWithSyntaxError = 'a { color red }'
const error = await t.throwsAsync(analyzer(cssWithSyntaxError))

Expand All @@ -11,11 +11,11 @@ test('Breaks with invalid CSS', async t => {
)
})

test('Passes with valid CSS', async t => {
test('it passes with valid CSS', async t => {
await t.notThrowsAsync(analyzer('body {}'))
})

test('Returns the correct analysis object structure', async t => {
test('it returns the correct analysis object structure', async t => {
const actual = await analyzer('foo{}')
const expected = {
'atrules.charsets.total': 0,
Expand Down Expand Up @@ -103,6 +103,8 @@ test('Returns the correct analysis object structure', async t => {
'selectors.browserhacks.unique': [],
'selectors.browserhacks.totalUnique': 0,
'stylesheets.cohesion.average': 0,
'stylesheets.cohesion.min.count': 0,
'stylesheets.cohesion.min.value': null,
'stylesheets.filesize.compressed.brotli.compressionRatio': -0.8,
'stylesheets.filesize.compressed.brotli.totalBytes': 9,
'stylesheets.filesize.compressed.gzip.compressionRatio': -4,
Expand Down
61 changes: 55 additions & 6 deletions test/analyzer/stylesheets/cohesion.js
@@ -1,12 +1,61 @@
const test = require('ava')
const analyze = require('../../../src/analyzer/stylesheets/cohesion')

test('it calculates cohesion based on the ratio of total declarations and total rules', t => {
const {average: actual} = analyze({total: 2}, {total: 4})
t.is(actual, 2)
test('it calculates average cohesion based on the ratio of total declarations and total rules', t => {
const actual = analyze([
{
declarations: [
{property: 'a', value: 'a'},
{property: 'b', value: 'b'},
{property: 'c', value: 'c'},
{property: 'd', value: 'd'}
]
},
{
declarations: [{property: 'a', value: 'a'}, {property: 'b', value: 'b'}]
}
])
t.is(actual.average, 3)
})

test('it calculates cohesion correctly if there are no rules and/or declarations', t => {
const {average: actual} = analyze({total: 0}, {total: 0})
t.is(actual, 0)
test('it calculates average cohesion correctly if there are no rules and/or declarations', t => {
const actual = analyze([])
t.is(actual.average, 0)
})

test('it calculates lowest cohesion as the rule with the most declarations', t => {
const ruleWithManyDeclarations = {
selectors: ['test'],
declarations: [
{property: 'a', value: 'a'},
{property: 'b', value: 'b'},
{property: 'c', value: 'c'},
{property: 'd', value: 'd'}
]
}
const fixture = [
ruleWithManyDeclarations,
{
declarations: [{property: 'a', value: 'a'}]
}
]
const actual = analyze(fixture)

t.is(actual.min.count, 4)
t.deepEqual(actual.min.value, ruleWithManyDeclarations)
})

test('it calculates lowest cohesion correctly if there are no declarations', t => {
const actualWithNoRules = analyze([])
t.is(actualWithNoRules.min.count, 0)
t.is(actualWithNoRules.min.value, null)

const actualWithNoDeclarations = analyze([
{
selectors: ['a'],
declarations: []
}
])
t.is(actualWithNoDeclarations.min.count, 0)
t.is(actualWithNoDeclarations.min.value, null)
})
8 changes: 6 additions & 2 deletions test/analyzer/stylesheets/index.js
Expand Up @@ -3,11 +3,11 @@ const analyze = require('../../../src/analyzer/stylesheets')

const FIXTURE = {
rawCss: '',
rules: [],
selectors: {
total: 0,
browserhacks: {total: 0, totalUnique: 0}
},
declarations: {total: 0},
atrules: {
mediaqueries: {browserhacks: {total: 0, totalUnique: 0}},
supports: {browserhacks: {total: 0, totalUnique: 0}}
Expand Down Expand Up @@ -36,7 +36,11 @@ test('it responds with the correct structure', t => {
},
simplicity: 0,
cohesion: {
average: 0
average: 0,
min: {
count: 0,
value: null
}
},
browserhacks: {
total: 0,
Expand Down
4 changes: 2 additions & 2 deletions test/analyzer/stylesheets/simplicity.js
Expand Up @@ -2,13 +2,13 @@ const test = require('ava')
const analyze = require('../../../src/analyzer/stylesheets/simplicity')

test('it calculates simplicity based on the ratio of total selectors and total rules', t => {
const actual = analyze({total: 1}, {total: 2})
const actual = analyze([{}], {total: 2})
t.is(actual, 0.5)
})

// Necessary test case for CSS files that contain
// only a couple of @font-face rules, like Google Fonts
test('it calculates simplicity correctly if there are no rules and/or selectors', t => {
const actual = analyze({total: 0}, {total: 0})
const actual = analyze([], {total: 0})
t.is(actual, 0)
})

0 comments on commit 5cb55de

Please sign in to comment.