Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add a colonSpace rule to enfoce a space after a colon #443

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .stylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"blocks": false,
"brackets": false,
"colons": "always",
"colonSpace": "always",
"colors": {
"expect": "always"
},
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,12 @@ Example if 'always': prefer `margin: 0` over `margin 0`

Example if 'never: prefer `margin 0` over `margin: 0`

### colonSpace ( default: 'always', 'always' || 'never' || false )
Enforce or disallow spaces after colons

Example if always: prefer `margin: 0` over `margin:0`

Example if never: prefer `margin:0` over `margin: 0`

### colors ( default: 'always' || false )
When 'always', enforce variables when defining hex values
Expand Down
49 changes: 49 additions & 0 deletions src/checks/colonSpace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
'use strict'

var validJSON = require( '../data/valid.json' )
// we only want to check colons on properties/values
var ignoreRe = /( ^[&$=#>.]|\.[a-zA-Z]|#[a-zA-Z]| \+ | , | = | ~ | > | &| {|}|\(|if|for(?!\w)|else|return|@block|@media|@import|@extend|@require|,$)/m

/**
* @description if set to always, enforces spaces after colons. if set to never, disallows spaces
* @param {string} [line] curr line being linted
* @param {string} [origLine] curr line before being stripped
* @returns {boolean} true if space missing, false if not
*/
var colonSpace = function( line, origLine ) {
if ( ignoreRe.test( origLine ) || this.state.context === 0 || origLine.indexOf( ':' ) === -1 ) { return }

var hasSpace
var hasPseudo = false
var hasScope = false
var arr = this.splitAndStrip( new RegExp( /\s/ ), origLine )

if ( this.state.conf === 'always' || this.state.conf === 'never' ) {
// check for pseudo selector
hasPseudo = validJSON.pseudo.some( function( val ) {
return origLine.indexOf( val ) !== -1
} )

// check for scope selector
hasScope = validJSON.scope.some( function( val ) {
return origLine.indexOf( val ) !== -1
} )

if ( !hasPseudo && !hasScope ) {
hasSpace = arr.length > 1 && arr[0].indexOf( ':' ) === arr[0].length - 1
}
}

// if spaces should be follow commas, but there is no space on the line
if ( this.state.conf === 'always' && hasSpace === false ) {
this.msg( 'colons must be followed by a space for readability', origLine.indexOf( ':' ) )
}
// if spaces should not be followed by a comma, but there are spaces anyway
else if ( this.state.conf === 'never' && hasSpace === true ) {
this.msg( 'spaces after colons are not allowed', origLine.indexOf( ':' ) )
}

return hasSpace
}

module.exports = colonSpace
1 change: 1 addition & 0 deletions src/checks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ var linterMethods = stampit().methods( {
blocks: require( './blocks' ),
brackets: require( './brackets' ),
colons: require( './colons' ),
colonSpace: require( './colonSpace' ),
colors: require( './colors' ),
commaSpace: require( './commaSpace' ),
commentSpace: require( './commentSpace' ),
Expand Down
2 changes: 2 additions & 0 deletions src/core/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ var config = {
brackets: 'never',
// enforce or disallow colons
colons: 'always',
// check for space after colons
colonSpace: 'always',
// check for hex colors used without variables
colors: 'always',
// check for spaces after commas (0, 0, 0, .18)
Expand Down
91 changes: 91 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,97 @@ describe( 'Linter Style Checks: ', function() {
} )
} )

describe( 'colon space: prefer margin: 0 over margin:0', function() {
var colonSpaceTest = lint.colonSpace.bind( app )

beforeEach( function() {
app.state.conf = 'always'
} )

it( 'false if no space is found', function() {
app.state.context = 1
assert.equal( false, colonSpaceTest( '', 'margin:0 auto' ) )
assert.equal( false, colonSpaceTest( '', 'margin:0' ) )
} )


it( 'true if space is found', function() {
app.state.context = 1
assert.equal( true, colonSpaceTest( '', 'margin: 0 auto' ) )
assert.equal( true, colonSpaceTest( '', 'margin: 0' ) )
assert.equal( true, colonSpaceTest( '', 'grid-template-areas: "icon label"' ) )
} )

it( 'undefined if syntax or css selector', function() {
assert.equal( undefined, colonSpaceTest( '', '#id' ) )
assert.equal( undefined, colonSpaceTest( '', '$.some-class' ) )
assert.equal( undefined, colonSpaceTest( '', '> child selector' ) )
assert.equal( undefined, colonSpaceTest( '', '.class-name' ) )
assert.equal( undefined, colonSpaceTest( '', 'for ( 0..9 )' ) )
assert.equal( undefined, colonSpaceTest( '', '@media $med' ) )
assert.equal( undefined, colonSpaceTest( '', '@extend $med' ) )
assert.equal( undefined, colonSpaceTest( '', '@extends $med' ) )
assert.equal( undefined, colonSpaceTest( '', '@import _some-file' ) )
assert.equal( undefined, colonSpaceTest( '', '.class-name, #id-name' ) )
assert.equal( undefined, colonSpaceTest( '', '.class-name + #id-name' ) )
assert.equal( undefined, colonSpaceTest( '', 'p ~ ul' ) )
assert.equal( undefined, colonSpaceTest( '', 'p > ul' ) )
assert.equal( undefined, colonSpaceTest( '', 'if ( $var == 50px )' ) )
assert.equal( undefined, colonSpaceTest( '', 'hash = {' ) )
assert.equal( undefined, colonSpaceTest( '', '}' ) )
assert.equal( undefined, colonSpaceTest( '', '.class-name a' ) )
assert.equal( undefined, colonSpaceTest( '', '&.class-name a' ) )
assert.equal( undefined, colonSpaceTest( '', '&:active' ) )
assert.equal( undefined, colonSpaceTest( '', 'return: $value' ) )
assert.equal( undefined, colonSpaceTest( '', 'return $value' ) )
assert.equal( undefined, colonSpaceTest( '', '@media screen and (max-width: 1183px)' ) )
} )
} )

describe( 'colon space: prefer margin:0 over margin: 0', function() {
var colonSpaceTest = lint.colonSpace.bind( app )

beforeEach( function() {
app.state.conf = 'never'
} )

it( 'true if no space is found', function() {
app.state.context = 1
assert.equal( false, colonSpaceTest( '', 'margin:0 auto' ) )
assert.equal( false, colonSpaceTest( '', 'margin:0' ) )
} )

it( 'undefined if no colon', function() {
app.state.context = 1
assert.equal( undefined, colonSpaceTest( '', 'margin 0 auto' ) )
} )

it( 'undefined if syntax or css selector', function() {
assert.equal( undefined, colonSpaceTest( '', '#id' ) )
assert.equal( undefined, colonSpaceTest( '', '$.some-class' ) )
assert.equal( undefined, colonSpaceTest( '', '> child selector' ) )
assert.equal( undefined, colonSpaceTest( '', '.class-name' ) )
assert.equal( undefined, colonSpaceTest( '', 'for ( 0..9 )' ) )
assert.equal( undefined, colonSpaceTest( '', '@media $med' ) )
assert.equal( undefined, colonSpaceTest( '', '@extend $med' ) )
assert.equal( undefined, colonSpaceTest( '', '@extends $med' ) )
assert.equal( undefined, colonSpaceTest( '', '@import _some-file' ) )
assert.equal( undefined, colonSpaceTest( '', '.class-name, #id-name' ) )
assert.equal( undefined, colonSpaceTest( '', '.class-name + #id-name' ) )
assert.equal( undefined, colonSpaceTest( '', 'p ~ ul' ) )
assert.equal( undefined, colonSpaceTest( '', 'p > ul' ) )
assert.equal( undefined, colonSpaceTest( '', 'if ( $var == 50px )' ) )
assert.equal( undefined, colonSpaceTest( '', 'hash = {' ) )
assert.equal( undefined, colonSpaceTest( '', '}' ) )
assert.equal( undefined, colonSpaceTest( '', '.class-name a' ) )
assert.equal( undefined, colonSpaceTest( '', '&.class-name a' ) )
assert.equal( undefined, colonSpaceTest( '', '&:active' ) )
assert.equal( undefined, colonSpaceTest( '', 'return: $value' ) )
assert.equal( undefined, colonSpaceTest( '', 'return $value' ) )
assert.equal( undefined, colonSpaceTest( '', '@media screen and (max-width: 1183px)' ) )
} )
} )

describe( 'colors', function() {
var colorsTest = lint.colors.bind( app )

Expand Down