├── .commitlintrc.yml ├── .editorconfig ├── .eslintrc ├── .github ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .npmignore ├── .npmrc ├── .nvmrc ├── .travis.yml ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── appveyor.yml ├── bin └── sass-lint.js ├── data ├── functions.yml ├── literals.yml ├── pseudoClasses.yml └── pseudoElements.yml ├── docs ├── .sasslintrc ├── cli │ └── readme.md ├── options │ ├── cache-config.md │ ├── config-file.md │ ├── cwd.md │ ├── formatter.md │ ├── max-warnings.md │ ├── merge-default-rules.md │ └── output-file.md ├── rules │ ├── attribute-quotes.md │ ├── bem-depth.md │ ├── border-zero.md │ ├── brace-style.md │ ├── class-name-format.md │ ├── clean-import-paths.md │ ├── declarations-before-nesting.md │ ├── empty-args.md │ ├── empty-line-between-blocks.md │ ├── extends-before-declarations.md │ ├── extends-before-mixins.md │ ├── final-newline.md │ ├── force-attribute-nesting.md │ ├── force-element-nesting.md │ ├── force-pseudo-nesting.md │ ├── function-name-format.md │ ├── hex-length.md │ ├── hex-notation.md │ ├── id-name-format.md │ ├── indentation.md │ ├── leading-zero.md │ ├── max-file-line-count.md │ ├── max-line-length.md │ ├── mixin-name-format.md │ ├── mixins-before-declarations.md │ ├── nesting-depth.md │ ├── no-at-rule-vendor-prefix.md │ ├── no-attribute-selectors.md │ ├── no-color-hex.md │ ├── no-color-keywords.md │ ├── no-color-literals.md │ ├── no-combinators.md │ ├── no-css-comments.md │ ├── no-debug.md │ ├── no-disallowed-properties.md │ ├── no-disallowed-property-values.md │ ├── no-duplicate-properties.md │ ├── no-empty-rulesets.md │ ├── no-extends.md │ ├── no-ids.md │ ├── no-important.md │ ├── no-invalid-hex.md │ ├── no-media-feature-vendor-prefix.md │ ├── no-mergeable-selectors.md │ ├── no-misspelled-properties.md │ ├── no-property-vendor-prefix.md │ ├── no-qualifying-elements.md │ ├── no-selector-vendor-prefix.md │ ├── no-trailing-whitespace.md │ ├── no-trailing-zero.md │ ├── no-transition-all.md │ ├── no-universal-selectors.md │ ├── no-url-domains.md │ ├── no-url-protocols.md │ ├── no-value-vendor-prefix.md │ ├── no-warn.md │ ├── one-declaration-per-line.md │ ├── placeholder-in-extend.md │ ├── placeholder-name-format.md │ ├── property-sort-order.md │ ├── property-units.md │ ├── pseudo-element.md │ ├── quotes.md │ ├── shorthand-values.md │ ├── single-line-per-selector.md │ ├── space-after-bang.md │ ├── space-after-colon.md │ ├── space-after-comma.md │ ├── space-around-operator.md │ ├── space-before-bang.md │ ├── space-before-brace.md │ ├── space-before-colon.md │ ├── space-between-parens.md │ ├── trailing-semicolon.md │ ├── url-quotes.md │ ├── variable-for-property.md │ ├── variable-name-format.md │ └── zero-unit.md ├── sass-lint.yml └── toggle-rules-in-src.md ├── index.js ├── lib ├── config-helpers.js ├── config.js ├── config │ ├── property-sort-orders │ │ ├── concentric.yml │ │ ├── recess.yml │ │ └── smacss.yml │ └── sass-lint.yml ├── exceptions.js ├── format │ ├── LICENSE │ ├── formatters │ │ ├── checkstyle.js │ │ ├── compact.js │ │ ├── html-template-message.html │ │ ├── html-template-page.html │ │ ├── html-template-result.html │ │ ├── html.js │ │ ├── json.js │ │ ├── junit.js │ │ ├── stylish.js │ │ ├── tap.js │ │ ├── unix.js │ │ └── visualstudio.js │ └── getFormatter.js ├── groot.js ├── helpers-autoprefixer.js ├── helpers.js ├── ruleToggler.js ├── rules.js ├── rules │ ├── attribute-quotes.js │ ├── bem-depth.js │ ├── border-zero.js │ ├── brace-style.js │ ├── class-name-format.js │ ├── clean-import-paths.js │ ├── declarations-before-nesting.js │ ├── empty-args.js │ ├── empty-line-between-blocks.js │ ├── extends-before-declarations.js │ ├── extends-before-mixins.js │ ├── final-newline.js │ ├── force-attribute-nesting.js │ ├── force-element-nesting.js │ ├── force-pseudo-nesting.js │ ├── function-name-format.js │ ├── hex-length.js │ ├── hex-notation.js │ ├── id-name-format.js │ ├── indentation.js │ ├── leading-zero.js │ ├── max-file-line-count.js │ ├── max-line-length.js │ ├── mixin-name-format.js │ ├── mixins-before-declarations.js │ ├── nesting-depth.js │ ├── no-at-rule-vendor-prefix.js │ ├── no-attribute-selectors.js │ ├── no-color-hex.js │ ├── no-color-keywords.js │ ├── no-color-literals.js │ ├── no-combinators.js │ ├── no-css-comments.js │ ├── no-debug.js │ ├── no-disallowed-properties.js │ ├── no-disallowed-property-values.js │ ├── no-duplicate-properties.js │ ├── no-empty-rulesets.js │ ├── no-extends.js │ ├── no-ids.js │ ├── no-important.js │ ├── no-invalid-hex.js │ ├── no-media-feature-vendor-prefix.js │ ├── no-mergeable-selectors.js │ ├── no-misspelled-properties.js │ ├── no-property-vendor-prefix.js │ ├── no-qualifying-elements.js │ ├── no-selector-vendor-prefix.js │ ├── no-trailing-whitespace.js │ ├── no-trailing-zero.js │ ├── no-transition-all.js │ ├── no-universal-selectors.js │ ├── no-url-domains.js │ ├── no-url-protocols.js │ ├── no-value-vendor-prefix.js │ ├── no-warn.js │ ├── one-declaration-per-line.js │ ├── placeholder-in-extend.js │ ├── placeholder-name-format.js │ ├── property-sort-order.js │ ├── property-units.js │ ├── pseudo-element.js │ ├── quotes.js │ ├── shorthand-values.js │ ├── single-line-per-selector.js │ ├── space-after-bang.js │ ├── space-after-colon.js │ ├── space-after-comma.js │ ├── space-around-operator.js │ ├── space-before-bang.js │ ├── space-before-brace.js │ ├── space-before-colon.js │ ├── space-between-parens.js │ ├── trailing-semicolon.js │ ├── url-quotes.js │ ├── variable-for-property.js │ ├── variable-name-format.js │ └── zero-unit.js └── selector-helpers.js ├── mocha.opts ├── package-lock.json ├── package.json └── tests ├── bom-utf8 ├── starts-with-mixin-utf8-bom.scss └── var-utf8-bom.scss ├── cli.js ├── cli ├── cli-clean.scss ├── cli-error.sass ├── cli-error.scss ├── cli-warn.scss ├── cli.scss └── cli.txt ├── config-helpers.js ├── config.js ├── dir-test └── dir.scss │ └── test.scss ├── failures.js ├── formatters ├── checkstyle.js ├── compact.js ├── fixtures │ ├── broken.js │ └── simple.js ├── html.js ├── json.js ├── junit.js ├── stylish.js ├── tap.js ├── unix.js └── visualstudio.js ├── getFormatter.js ├── helpers ├── addUnique.js ├── attemptTraversal.js ├── collectSuffixExtensions.js ├── getMessageType.js ├── hasEOL.js ├── helpers.js ├── isCamelCase.js ├── isEmptyLine.js ├── isEqual.js ├── isHyphenatedBEM.js ├── isHyphenatedLowerCase.js ├── isLowerCase.js ├── isNestable.js ├── isNewLine.js ├── isNumber.js ├── isPartialStringMatch.js ├── isPascalCase.js ├── isSnakeCase.js ├── isSpace.js ├── isStrictBEM.js ├── isUnique.js ├── isUpperCase.js ├── isValidHex.js ├── loadConfigFile.js ├── propertySearch.js ├── sortDetects.js ├── stripBom.js ├── stripLastSpace.js ├── stripPrefix.js └── stripQuotes.js ├── main.js ├── output.js ├── ruleToggler.js ├── rules ├── _lint.js ├── attribute-quotes.js ├── bem-depth.js ├── border-zero.js ├── brace-style.js ├── class-name-format.js ├── clean-import-paths.js ├── declarations-before-nesting.js ├── empty-args.js ├── empty-line-between-blocks.js ├── extends-before-declarations.js ├── extends-before-mixins.js ├── final-newline.js ├── force-attribute-nesting.js ├── force-element-nesting.js ├── force-pseudo-nesting.js ├── function-name-format.js ├── hex-length.js ├── hex-notation.js ├── id-name-format.js ├── indentation.js ├── leading-zero.js ├── max-file-line-count.js ├── max-line-length.js ├── mixin-name-format.js ├── mixins-before-declarations.js ├── nesting-depth.js ├── no-at-rule-vendor-prefix.js ├── no-attribute-selectors.js ├── no-color-hex.js ├── no-color-keywords.js ├── no-color-literals.js ├── no-combinators.js ├── no-css-comments.js ├── no-debug.js ├── no-disallowed-properties.js ├── no-disallowed-property-values.js ├── no-duplicate-properties.js ├── no-empty-rulesets.js ├── no-extends.js ├── no-ids.js ├── no-important.js ├── no-invalid-hex.js ├── no-media-feature-vendor-prefix.js ├── no-mergeable-selectors.js ├── no-misspelled-properties.js ├── no-property-vendor-prefix.js ├── no-qualifying-elements.js ├── no-selector-vendor-prefix.js ├── no-trailing-whitespace.js ├── no-trailing-zero.js ├── no-transition-all.js ├── no-universal-selectors.js ├── no-url-domains.js ├── no-url-protocols.js ├── no-value-vendor-prefix.js ├── no-warn.js ├── one-declaration-per-line.js ├── placeholder-in-extend.js ├── placeholder-name-format.js ├── property-sort-order.js ├── property-units.js ├── pseudo-element.js ├── quotes.js ├── shorthand-values.js ├── single-line-per-selector.js ├── space-after-bang.js ├── space-after-colon.js ├── space-after-comma.js ├── space-around-operator.js ├── space-before-bang.js ├── space-before-brace.js ├── space-before-colon.js ├── space-between-parens.js ├── trailing-semicolon.js ├── url-quotes.js ├── variable-for-property.js ├── variable-name-format.js └── zero-unit.js ├── sass ├── attribute-quotes.sass ├── attribute-quotes.scss ├── bem-depth.sass ├── bem-depth.scss ├── border-zero.sass ├── border-zero.scss ├── brace-style.scss ├── class-name-format.sass ├── class-name-format.scss ├── clean-import-paths.sass ├── clean-import-paths.scss ├── declarations-before-nesting.sass ├── declarations-before-nesting.scss ├── empty-args.sass ├── empty-args.scss ├── empty-file.sass ├── empty-file.scss ├── empty-line-between-blocks.sass ├── empty-line-between-blocks.scss ├── empty-line-with-comments.sass ├── empty-line-with-comments.scss ├── extends-before-declarations.sass ├── extends-before-declarations.scss ├── extends-before-mixins.sass ├── extends-before-mixins.scss ├── final-newline--import.sass ├── final-newline--import.scss ├── final-newline--nested.sass ├── final-newline--nested.scss ├── final-newline--none.sass ├── final-newline--none.scss ├── final-newline--return.sass ├── final-newline--return.scss ├── final-newline--space.sass ├── final-newline--space.scss ├── force-attribute-nesting.sass ├── force-attribute-nesting.scss ├── force-element-nesting.sass ├── force-element-nesting.scss ├── force-pseudo-nesting.sass ├── force-pseudo-nesting.scss ├── front-matter │ └── front-matter.scss ├── function-name-format.sass ├── function-name-format.scss ├── hex-length.sass ├── hex-length.scss ├── hex-notation.sass ├── hex-notation.scss ├── id-name-format.sass ├── id-name-format.scss ├── indentation │ ├── indentation-spaces.sass │ ├── indentation-spaces.scss │ ├── indentation-tabs.sass │ └── indentation-tabs.scss ├── leading-zero.sass ├── leading-zero.scss ├── max-file-line-count.sass ├── max-file-line-count.scss ├── max-line-length.sass ├── max-line-length.scss ├── mixin-name-format.sass ├── mixin-name-format.scss ├── mixins-before-declarations.sass ├── mixins-before-declarations.scss ├── nesting-depth.sass ├── nesting-depth.scss ├── no-at-rule-vendor-prefix.sass ├── no-at-rule-vendor-prefix.scss ├── no-attribute-selectors.sass ├── no-attribute-selectors.scss ├── no-color-hex.sass ├── no-color-hex.scss ├── no-color-keywords.sass ├── no-color-keywords.scss ├── no-color-literals.sass ├── no-color-literals.scss ├── no-combinators.sass ├── no-combinators.scss ├── no-css-comments.sass ├── no-css-comments.scss ├── no-debug.sass ├── no-debug.scss ├── no-disallowed-properties.sass ├── no-disallowed-properties.scss ├── no-disallowed-property-values.sass ├── no-disallowed-property-values.scss ├── no-duplicate-properties.sass ├── no-duplicate-properties.scss ├── no-empty-rulesets.scss ├── no-extends.sass ├── no-extends.scss ├── no-ids.sass ├── no-ids.scss ├── no-important.sass ├── no-important.scss ├── no-invalid-hex.sass ├── no-invalid-hex.scss ├── no-media-feature-vendor-prefix.sass ├── no-media-feature-vendor-prefix.scss ├── no-mergeable-selectors.sass ├── no-mergeable-selectors.scss ├── no-misspelled-properties.sass ├── no-misspelled-properties.scss ├── no-property-vendor-prefix.sass ├── no-property-vendor-prefix.scss ├── no-qualifying-elements.sass ├── no-qualifying-elements.scss ├── no-selector-vendor-prefix.sass ├── no-selector-vendor-prefix.scss ├── no-trailing-whitespace.sass ├── no-trailing-whitespace.scss ├── no-trailing-zero.sass ├── no-trailing-zero.scss ├── no-transition-all.sass ├── no-transition-all.scss ├── no-universal-selectors.sass ├── no-universal-selectors.scss ├── no-url-domains.sass ├── no-url-domains.scss ├── no-url-protocols.sass ├── no-url-protocols.scss ├── no-value-vendor-prefix.sass ├── no-value-vendor-prefix.scss ├── no-warn.sass ├── no-warn.scss ├── one-declaration-per-line.scss ├── parse.scss ├── placeholder-in-extend.sass ├── placeholder-in-extend.scss ├── placeholder-name-format.sass ├── placeholder-name-format.scss ├── property-sort-order.sass ├── property-sort-order.scss ├── property-units.sass ├── property-units.scss ├── pseudo-element.sass ├── pseudo-element.scss ├── quotes.sass ├── quotes.scss ├── ruleToggler-disable-a-block.sass ├── ruleToggler-disable-a-block.scss ├── ruleToggler-disable-a-line.sass ├── ruleToggler-disable-a-line.scss ├── ruleToggler-disable-a-rule.sass ├── ruleToggler-disable-a-rule.scss ├── ruleToggler-disable-all-then-reenable.sass ├── ruleToggler-disable-all-then-reenable.scss ├── ruleToggler-disable-all.sass ├── ruleToggler-disable-all.scss ├── ruleToggler-disable-multiple-rules.sass ├── ruleToggler-disable-multiple-rules.scss ├── ruleToggler-disable-next-line.sass ├── ruleToggler-disable-next-line.scss ├── ruleToggler-disable-then-enable.sass ├── ruleToggler-disable-then-enable.scss ├── ruleToggler-empty-comment.sass ├── ruleToggler-empty-comment.scss ├── ruleToggler-guarantee-order.sass ├── ruleToggler-guarantee-order.scss ├── ruleToggler-ignore-unknown.sass ├── ruleToggler-ignore-unknown.scss ├── selector-helpers │ └── selector-helpers.scss ├── shorthand-values.sass ├── shorthand-values.scss ├── single-line-per-selector.sass ├── single-line-per-selector.scss ├── space-after-bang.sass ├── space-after-bang.scss ├── space-after-colon.sass ├── space-after-colon.scss ├── space-after-comma.sass ├── space-after-comma.scss ├── space-around-operator.sass ├── space-around-operator.scss ├── space-before-bang.sass ├── space-before-bang.scss ├── space-before-brace.scss ├── space-before-colon.sass ├── space-before-colon.scss ├── space-between-parens.sass ├── space-between-parens.scss ├── success.scss ├── trailing-semicolon.scss ├── url-quotes.sass ├── url-quotes.scss ├── variable-for-property.sass ├── variable-for-property.scss ├── variable-name-format.sass ├── variable-name-format.scss ├── zero-unit.sass └── zero-unit.scss ├── selector-helpers └── selectorHelpers.js ├── testFile.txt └── yml ├── .blank.yml ├── .color-keyword-errors.yml ├── .error-output.yml ├── .extend-a1.yml ├── .extend-a2.yml ├── .ignore-file.yml ├── .indentation-error.yml ├── .indentation-warn.yml ├── .json-lint.yml ├── .max-0-warnings.yml ├── .max-10-warnings.yml ├── .max-100-warnings.yml ├── .multiple-ignore-strings.yml ├── .multiple-ignores.yml ├── .multiple-inputs.yml ├── .no-merge-default.yml ├── .sass-lint.yml └── .sass-lint.yml ├── .sasslintrc └── .sasslintrc ├── .single-input-include-string.yml ├── .stylish-errors.yml ├── .stylish-output.yml └── extend ├── .extend-b.yml ├── .extend-c.yml └── find-file-test └── .gitignore /.commitlintrc.yml: -------------------------------------------------------------------------------- 1 | extends: 2 | - '@commitlint/config-conventional' -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | 10 | # Change these settings to your own preference 11 | indent_style = space 12 | indent_size = 2 13 | 14 | # We recommend you to keep these unchanged 15 | end_of_line = lf 16 | charset = utf-8 17 | trim_trailing_whitespace = true 18 | insert_final_newline = true 19 | 20 | [*.md] 21 | trim_trailing_whitespace = false 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | What version of Sass Lint are you using? 12 | 13 | Please include any relevant parts of your configuration 14 | 15 | What did you do? Please include the actual source code causing the issue. 16 | 17 | What did you expect to happen? 18 | 19 | What actually happened? Please include any error messages given to you by Sass Lint. 20 | 21 | If you're using a IDE plugin have you tried the CLI too? 22 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 13 | 14 | **What do the changes you have made achieve?** 15 | 16 | **Are there any new warning messages?** 17 | 18 | **Have you written tests?** 19 | 20 | **Have you included relevant documentation** 21 | 22 | **Which issues does this resolve?** 23 | 24 | `` 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # OSX 11 | ._* 12 | .DS_Store 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | .nyc_output 20 | 21 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 22 | .grunt 23 | 24 | # Compiled binary addons (http://nodejs.org/api/addons.html) 25 | build/Release 26 | 27 | # Dependency directory 28 | # Commenting this out is preferred by some people, see 29 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 30 | node_modules 31 | 32 | # Users Environment Variables 33 | .lock-wscript 34 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .github 2 | coverage 3 | docs 4 | tests 5 | .editorconfig 6 | .eslintrc 7 | .gitignore 8 | .npmignore 9 | .npmrc 10 | .travis.yml 11 | .nvmrc 12 | appveyor.yml 13 | CONTRIBUTING.md 14 | CODE_OF_CONDUCT.md 15 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | message=:shipit: v%s 2 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 6 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '6' 4 | - '9' 5 | - 'stable' 6 | cache: 7 | directories: 8 | - node_modules 9 | install: 10 | - npm install 11 | script: 12 | - npm test 13 | after_script: 14 | - npm run coverage 15 | jobs: 16 | include: 17 | - stage: deploy 18 | node_js: stable 19 | script: "npm run semantic-release" 20 | notifications: 21 | slack: 22 | secure: RrEbq2xE1hWdog4AckkaKDnIYYwo5VdjPcFNhRJbn/7KI0fKeZVCKZy1Ww7aaJGth7R7UX415sEV1U6RrjFyhnBb6Sh+rh8fKTvcvuTbENZW45SbtUD+xmgOvb2kfk4PzgD5Q457DpchAZD7W+E+9qr3xI3Uvh4II1uhDmSKiLI= 23 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | Sass is more than a technology; Sass is driven by the community of individuals 2 | that power its development and use every day. As a community, we want to embrace 3 | the very differences that have made our collaboration so powerful, and work 4 | together to provide the best environment for learning, growing, and sharing of 5 | ideas. It is imperative that we keep Sass a fun, welcoming, challenging, and 6 | fair place to play. 7 | 8 | [The full community guidelines can be found on the Sass website.][link] 9 | 10 | [link]: http://sass-lang.com/community-guidelines 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Sam Richard 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # CRLF Line Endings 2 | init: 3 | - git config --global core.autocrlf true 4 | 5 | # Test against this version of Node.js 6 | environment: 7 | matrix: 8 | - nodejs_version: '6' 9 | - nodejs_version: '9' 10 | # Latest stable version of Node 11 | - nodejs_version: 'stable' 12 | 13 | # Install scripts. (runs after repo cloning) 14 | install: 15 | # Get the latest stable version of Node.js or io.js 16 | - ps: Install-Product node $env:nodejs_version 17 | # install modules 18 | - npm install 19 | 20 | # Post-install test scripts. 21 | test_script: 22 | # Output useful info for debugging. 23 | - node --version 24 | - npm --version 25 | # run tests 26 | - npm test 27 | 28 | # Don't actually build. 29 | build: off 30 | -------------------------------------------------------------------------------- /data/pseudoClasses.yml: -------------------------------------------------------------------------------- 1 | active 2 | any 3 | checked 4 | default 5 | dir 6 | disabled 7 | empty 8 | enabled 9 | first 10 | first-child 11 | first-of-type 12 | fullscreen 13 | focus 14 | hover 15 | indeterminate 16 | in-range 17 | invalid 18 | lang 19 | last-child 20 | last-of-type 21 | left 22 | link 23 | not 24 | nth-child 25 | nth-last-child 26 | nth-last-of-type 27 | nth-of-type 28 | only-child 29 | only-of-type 30 | optional 31 | out-of-range 32 | read-only 33 | read-write 34 | required 35 | right 36 | root 37 | scope 38 | target 39 | valid 40 | visited 41 | -------------------------------------------------------------------------------- /data/pseudoElements.yml: -------------------------------------------------------------------------------- 1 | after 2 | before 3 | cue 4 | first-letter 5 | first-line 6 | selection 7 | backdrop 8 | placeholder 9 | marker 10 | spelling-error 11 | grammar-error 12 | -------------------------------------------------------------------------------- /docs/options/cache-config.md: -------------------------------------------------------------------------------- 1 | # Cache Config 2 | 3 | Option `cache-config` will tell Sass Lint to cache the current configuration for each invocation of sass-lint. This option is disabled by default but you may consider enabling it if you're not planning on modifying your `.sass-lint.yml` config file as there will be a small performance gain. 4 | 5 | ## Options 6 | 7 | * `true`/`false` (defaults to `false`) 8 | -------------------------------------------------------------------------------- /docs/options/cwd.md: -------------------------------------------------------------------------------- 1 | # cwd 2 | 3 | Option `cwd` will determine a directory that sass-lint should use as the base directory when it looks for files / paths etc. This is useful for specifying standard directory structures across teams for example. 4 | 5 | ## Options 6 | 7 | * Default: `$ process.cwd();` 8 | -------------------------------------------------------------------------------- /docs/options/max-warnings.md: -------------------------------------------------------------------------------- 1 | # Max warnings 2 | 3 | An error will be thrown if the total number of warnings exceeds the `max-warnings` setting. 4 | 5 | > Please note, if you're using this option with the sass-lint CLI and you're specifying the `--no-exit / -q` option too, you will not see an error but an error code of 1 will still be thrown. 6 | 7 | ## Examples 8 | 9 | This can be set as a command-line option: 10 | 11 | ``` bash 12 | $ sass-lint --max-warnings 50 13 | ``` 14 | 15 | In `.sass-lint.yml`: 16 | 17 | ``` yaml 18 | options: 19 | max-warnings: 50 20 | ``` 21 | 22 | Or inside a script: 23 | 24 | ``` javascript 25 | var sassLint = require('sass-lint'), 26 | config = {options: {'max-warnings': 50}}; 27 | 28 | results = sassLint.lintFiles('sass/**/*.scss', config) 29 | sassLint.failOnError(results, config); 30 | ``` 31 | -------------------------------------------------------------------------------- /docs/options/output-file.md: -------------------------------------------------------------------------------- 1 | # Output File 2 | 3 | Option `output-file` will determine if formatted output should be written to a file. `output-file` should be set to a path plus file name relative to where Sass Lint is being run from. If not included, formatted output will be logged to the console. 4 | -------------------------------------------------------------------------------- /docs/rules/attribute-quotes.md: -------------------------------------------------------------------------------- 1 | # Attribute Quotes 2 | 3 | Rule `attribute-quotes` will enforce the use of quotes in attribute values. 4 | 5 | ## Options 6 | 7 | * `include`: `true`/`false` (defaults to `true`) 8 | 9 | ## Examples 10 | 11 | ### `include` 12 | 13 | When `include: true`, the following are allowed. When `include: false`, the following are disallowed: 14 | 15 | ```scss 16 | 17 | span[lang="pt"] { 18 | color: green; 19 | } 20 | 21 | span[lang~="en-us"] { 22 | color: blue; 23 | } 24 | 25 | span[class^="main"] { 26 | background-color: yellow; 27 | } 28 | 29 | a[href*="example"] { 30 | background-color: #CCCCCC; 31 | } 32 | 33 | input[type="email" i] { 34 | border-color: blue; 35 | } 36 | ``` 37 | 38 | When `include: false`, the following are allowed. When `include: true`, the following are disallowed: 39 | 40 | ```scss 41 | 42 | span[lang=pt] { 43 | color: green; 44 | } 45 | 46 | span[lang~=en-us] { 47 | color: blue; 48 | } 49 | 50 | span[class^=main] { 51 | background-color: yellow; 52 | } 53 | 54 | a[href*=example] { 55 | background-color: #CCCCCC; 56 | } 57 | 58 | input[type=email i] { 59 | border-color: blue; 60 | } 61 | ``` 62 | -------------------------------------------------------------------------------- /docs/rules/bem-depth.md: -------------------------------------------------------------------------------- 1 | # BEM Depth 2 | 3 | Rule `bem-depth` will enforce how many elements a BEM selector can contain. 4 | 5 | ## Options 6 | 7 | * `max-depth`: number (defaults to `1`) 8 | 9 | ## Examples 10 | 11 | When enabled (assuming `max-depth: 1`) the following are disallowed: 12 | 13 | ```scss 14 | 15 | .block { 16 | &__element { 17 | &__subelement { 18 | // two elements 19 | } 20 | } 21 | } 22 | 23 | .block__element__subelement__subelement-two { 24 | // three elements 25 | } 26 | ``` 27 | -------------------------------------------------------------------------------- /docs/rules/border-zero.md: -------------------------------------------------------------------------------- 1 | # Border Zero 2 | 3 | Rule `border-zero` will enforce whether one should use `0` or `none` when specifying a zero `border` value 4 | 5 | ## Options 6 | 7 | * `convention`: `'0'`/`'none'` (defaults to `0`) 8 | 9 | > If an invalid convention is provided the rule will default back to `convention: '0'`. An extra warning/error will also be thrown on `line 1` `column 1` of a file with a lint issue to inform you of this fact. 10 | 11 | ## Examples 12 | 13 | When `convention: '0'`, the following are allowed. When `convention: 'none'`, the following are disallowed: 14 | 15 | ```scss 16 | .foo { 17 | border: 0; 18 | } 19 | 20 | .bar { 21 | border-right: 0; 22 | } 23 | ``` 24 | 25 | When `convention: 'none'`, the following are allowed. When `convention: '0'`, the following are disallowed: 26 | 27 | ```scss 28 | .foo { 29 | border: none; 30 | } 31 | 32 | .bar { 33 | border-left: none; 34 | } 35 | ``` 36 | 37 | ### Invalid conventions 38 | 39 | When the invalid convention `convention: 'zero'` is supplied, the following are allowed as the rule defaults to `convention: '0'`. 40 | 41 | ```scss 42 | .foo { 43 | border: none; 44 | } 45 | 46 | .bar { 47 | border-left: 0; 48 | } 49 | ``` 50 | -------------------------------------------------------------------------------- /docs/rules/clean-import-paths.md: -------------------------------------------------------------------------------- 1 | # Clean Import Paths 2 | 3 | Rule `clean-import-paths` will enforce whether or not `@import` paths should have leading underscores and/or filename extensions. 4 | 5 | ## Options 6 | 7 | * `leading-underscore`: `true`/`false` (defaults to `false`) 8 | * `filename-extension`: `true`/`false` (defaults to `false`) 9 | 10 | 11 | ## Examples 12 | 13 | ### `leading-underscore` 14 | 15 | When `leading-underscore: false`, the following are allowed. When `leading-underscore: true`, the following are disallowed: 16 | 17 | ```scss 18 | @import 'foo'; 19 | @import 'bar/foo'; 20 | ``` 21 | 22 | When `leading-underscore: true`, the following are allowed. When `leading-underscore: false`, the following are disallowed: 23 | 24 | ```scss 25 | @import '_foo'; 26 | @import '_bar/foo'; 27 | ``` 28 | 29 | --- 30 | ### `filename-extension` 31 | 32 | When `filename-extension: false`, the following are allowed. When `filename-extension: true`, the following are disallowed: 33 | 34 | ```scss 35 | @import 'foo'; 36 | @import 'bar/foo'; 37 | ``` 38 | 39 | When `filename-extension: true`, the following are allowed. When `filename-extension: false`, the following are disallowed: 40 | 41 | ```scss 42 | @import 'foo.scss'; 43 | @import 'bar/foo.scss'; 44 | ``` 45 | -------------------------------------------------------------------------------- /docs/rules/declarations-before-nesting.md: -------------------------------------------------------------------------------- 1 | # Declarations Before Nesting 2 | 3 | Rule `declarations-before-nesting` will enforce that declarations should be written before nesting in a ruleset. 4 | 5 | ## Examples 6 | 7 | When enabled, the following are allowed: 8 | 9 | ```scss 10 | .foo { 11 | content: 'baz'; 12 | 13 | .bar { 14 | content: 'qux'; 15 | } 16 | } 17 | ``` 18 | 19 | When enabled, the following are disallowed: 20 | 21 | ```scss 22 | .foo { 23 | .bar { 24 | content: 'qux'; 25 | } 26 | 27 | content: 'baz'; 28 | } 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/rules/empty-args.md: -------------------------------------------------------------------------------- 1 | # Empty Args 2 | 3 | Rule `empty-args` will enforce whether or not parenthesis should be included if no arguments are defined or used, when declaring or invoking a mixin. 4 | 5 | ## Options 6 | 7 | * `include`: `true`/`false` (defaults to `false`) 8 | 9 | ## Examples 10 | 11 | When `include: false`, the following are allowed. When `include: true`, the following are disallowed: 12 | 13 | ```scss 14 | @mixin bar { 15 | padding: 10px; 16 | } 17 | 18 | .bar { 19 | @include bar; 20 | } 21 | ``` 22 | 23 | When `include: true`, the following are allowed. When `include: false`, the following are disallowed: 24 | 25 | ```scss 26 | @mixin foo() { 27 | padding: 10px; 28 | } 29 | 30 | .foo { 31 | @include foo(); 32 | } 33 | ``` 34 | -------------------------------------------------------------------------------- /docs/rules/extends-before-declarations.md: -------------------------------------------------------------------------------- 1 | # Extends Before Declarations 2 | 3 | Rule `extends-before-declarations` will enforce that extends should be written before declarations in a ruleset. 4 | 5 | ## Examples 6 | 7 | When enabled, the following are allowed: 8 | 9 | ```scss 10 | .foo { 11 | @extend %bar; 12 | content: 'baz'; 13 | } 14 | ``` 15 | 16 | When enabled, the following are disallowed: 17 | 18 | ```scss 19 | .foo { 20 | content: 'baz'; 21 | @extend %bar; 22 | } 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/rules/extends-before-mixins.md: -------------------------------------------------------------------------------- 1 | # Extends Before Mixins 2 | 3 | Rule `extends-before-mixins` will enforce that extends should be written before mixins in a ruleset. 4 | 5 | ## Examples 6 | 7 | When enabled, the following are allowed.: 8 | 9 | ```scss 10 | .foo { 11 | @extend %bar; 12 | @include baz; 13 | } 14 | ``` 15 | 16 | When enabled, the following are disallowed: 17 | 18 | ```scss 19 | .foo { 20 | @include baz; 21 | @extend %bar; 22 | } 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/rules/final-newline.md: -------------------------------------------------------------------------------- 1 | # Final Newline 2 | 3 | Rule `final-newline` will enforce whether or not files should end with a newline. 4 | 5 | ## Options 6 | 7 | * `include`: `true`/`false` (defaults to `true`) 8 | 9 | ## Examples 10 | 11 | When `include: true`, the following are allowed. When `include: false`, the following are disallowed: 12 | 13 | ```scss 14 | .foo { 15 | content: 'bar'; 16 | } 17 | // Newline under this comment at end of file 18 | 19 | ``` 20 | 21 | When `include: false`, the following are allowed. When `include: true`, the following are disallowed: 22 | 23 | ```scss 24 | .foo { 25 | content: 'bar'; 26 | } 27 | // No newline under this comment at end of file 28 | ``` 29 | -------------------------------------------------------------------------------- /docs/rules/force-attribute-nesting.md: -------------------------------------------------------------------------------- 1 | # Force Attribute Nesting 2 | 3 | Rule `force-attribute-nesting` will enforce the nesting of attributes 4 | 5 | 6 | ## Examples 7 | 8 | When enabled, the following are disallowed: 9 | ```scss 10 | input[type='radio'] { 11 | color: red; 12 | } 13 | 14 | a[target='_blank'] { 15 | content: ''; 16 | } 17 | 18 | .form { 19 | .class input[type='text'] { 20 | padding: 0; 21 | } 22 | } 23 | ``` 24 | 25 | When enabled, the following are allowed: 26 | 27 | ```scss 28 | input { 29 | &[type='radio'] { 30 | color: red; 31 | } 32 | } 33 | 34 | a { 35 | &[target='_blank'] { 36 | content: ''; 37 | } 38 | } 39 | 40 | .form { 41 | .class input { 42 | &[type='text'] { 43 | padding: 0; 44 | } 45 | } 46 | } 47 | ``` 48 | -------------------------------------------------------------------------------- /docs/rules/force-element-nesting.md: -------------------------------------------------------------------------------- 1 | # Force Element Nesting 2 | 3 | Rule `force-element-nesting` will enforce the nesting of elements 4 | 5 | ## Examples 6 | 7 | When enabled, the following are disallowed: 8 | 9 | ```scss 10 | div p { 11 | content: ''; 12 | } 13 | 14 | .parent { 15 | &__child h1 { 16 | content: ''; 17 | } 18 | } 19 | 20 | a[target="_blank"] span { 21 | content: ''; 22 | } 23 | ``` 24 | 25 | When enabled, the following are allowed: 26 | 27 | ```scss 28 | div { 29 | p { 30 | content: ''; 31 | } 32 | } 33 | 34 | .parent { 35 | &__child { 36 | h1 { 37 | content: ''; 38 | } 39 | } 40 | } 41 | 42 | a[target="_blank"] { 43 | span { 44 | content: ''; 45 | } 46 | } 47 | ``` 48 | -------------------------------------------------------------------------------- /docs/rules/force-pseudo-nesting.md: -------------------------------------------------------------------------------- 1 | # Force Pseudo Nesting 2 | 3 | Rule `force-pseudo-nesting` will enforce the nesting of pseudo elements/classes. 4 | 5 | 6 | ## Examples 7 | 8 | When enabled, the following are disallowed: 9 | ```scss 10 | p:nth-of-type(2) { 11 | margin: 0; 12 | } 13 | 14 | .parent { 15 | .child { 16 | p::first-line { 17 | color: #ff0000; 18 | } 19 | } 20 | } 21 | 22 | .parent { 23 | .child { 24 | .sub p::first-line { 25 | color: #ff0000; 26 | } 27 | } 28 | } 29 | ``` 30 | 31 | When enabled, the following are allowed: 32 | 33 | ```scss 34 | p { 35 | &:nth-of-type(2) { 36 | margin: 0; 37 | } 38 | } 39 | 40 | .parent { 41 | .child { 42 | p { 43 | &::first-line { 44 | color: #ff0000; 45 | } 46 | } 47 | } 48 | } 49 | 50 | .parent { 51 | .child { 52 | .sub p { 53 | &::first-line { 54 | color: #ff0000; 55 | } 56 | } 57 | } 58 | } 59 | ``` 60 | -------------------------------------------------------------------------------- /docs/rules/hex-length.md: -------------------------------------------------------------------------------- 1 | # Hex Length 2 | 3 | Rule `hex-length` will enforce the length of hexadecimal values 4 | 5 | ## Options 6 | 7 | * `style`: `short`/`long` (defaults to `short`) 8 | 9 | ## Examples 10 | 11 | When `style: short`, the following are allowed. When `style: long`, the following are disallowed: 12 | 13 | ```scss 14 | $foo-color: #456; 15 | 16 | .bar { 17 | background: linear-gradient(top, #3ff, #ddd); 18 | } 19 | 20 | .baz { 21 | color: #fff; 22 | } 23 | ``` 24 | 25 | When `style: long`, the following are allowed. When `style: short`, the following are disallowed: 26 | 27 | ```scss 28 | $foo-color: #445566; 29 | 30 | .bar { 31 | background: linear-gradient(top, #33ffff, #dddddd); 32 | } 33 | 34 | .baz { 35 | color: #ffffff; 36 | } 37 | ``` 38 | 39 | In both cases the following will be allowed as the values cannot be shortened: 40 | 41 | ```scss 42 | $quz-color: #abcdef; 43 | 44 | .qux { 45 | color: #123456; 46 | } 47 | ``` 48 | -------------------------------------------------------------------------------- /docs/rules/hex-notation.md: -------------------------------------------------------------------------------- 1 | # Hex Notation 2 | 3 | Rule `hex-notation` will enforce the case of hexadecimal values 4 | 5 | ## Options 6 | 7 | * `style`: `lowercase`/`uppercase` (defaults to `lowercase`) 8 | 9 | ## Examples 10 | 11 | When `style: lowercase`, the following are allowed. When `style: uppercase`, the following are disallowed: 12 | 13 | ```scss 14 | $foo-color: #fff; 15 | 16 | .bar { 17 | background: linear-gradient(top, #cc2, #44d); 18 | } 19 | 20 | .baz { 21 | color: #12a; 22 | } 23 | ``` 24 | 25 | When `style: uppercase`, the following are allowed. When `style: lowercase`, the following are disallowed: 26 | 27 | ```scss 28 | $foo-color: #FFF; 29 | 30 | .bar { 31 | background: linear-gradient(top, #CC2, #44D); 32 | } 33 | 34 | .baz { 35 | color: #12A; 36 | } 37 | ``` 38 | 39 | In both cases the following will be allowed as the values contain only numbers: 40 | 41 | ```scss 42 | .qux { 43 | color: #123; 44 | } 45 | ``` 46 | -------------------------------------------------------------------------------- /docs/rules/indentation.md: -------------------------------------------------------------------------------- 1 | # Indentation 2 | 3 | Rule `indentation` will enforce an indentation size (tabs and spaces) and it will also ensure that tabs and spaces are not mixed. 4 | 5 | The mixed spaces and tabs warnings check will take into account what you have set in your config file whether it should expect to see spaces or tabs. If it encounters a tab anywhere in a file when your rule config doesn't specify tabs it will flag a lint warning, Similarly for any whitespace using spaces when tabs are specified. Obviously spaces between properties and values etc are ignored. 6 | 7 | ## Options 8 | 9 | * `size`: `number` or `'tab'` (defaults to `2` spaces) 10 | 11 | ## Examples 12 | 13 | When enabled (assuming `size: 2`) the following are allowed: 14 | 15 | ```scss 16 | .foo { 17 | content: 'bar'; 18 | 19 | .baz { 20 | content: 'qux'; 21 | 22 | // Waldo 23 | &--waldo { 24 | content: 'alpha'; 25 | } 26 | } 27 | } 28 | ``` 29 | 30 | When enabled (assuming `size: 2`) the following are disallowed: 31 | 32 | ```scss 33 | .foo { 34 | content: 'bar'; 35 | .baz { 36 | content: 'qux'; 37 | // Waldo 38 | &--waldo { 39 | content: 'alpha'; 40 | } 41 | } 42 | } 43 | ``` 44 | -------------------------------------------------------------------------------- /docs/rules/leading-zero.md: -------------------------------------------------------------------------------- 1 | # Leading Zero 2 | 3 | Rule `leading-zero` will enforce whether or not decimal numbers should include a leading zero. 4 | 5 | ## Options 6 | 7 | * `include`: `true`/`false` (defaults to `false`) 8 | 9 | ## Examples 10 | 11 | When `include: false`, the following are allowed. When `include: true`, the following are disallowed: 12 | 13 | ```scss 14 | .foo { 15 | font-size: .5em; 16 | } 17 | ``` 18 | 19 | When `include: true`, the following are allowed. When `include: false`, the following are disallowed: 20 | 21 | ```scss 22 | .foo { 23 | font-size: 0.5em; 24 | } 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/rules/max-file-line-count.md: -------------------------------------------------------------------------------- 1 | # Max File Line Count 2 | 3 | Rule `max-file-line-count` will enforce that a file's length doesn't exceed a certain number of lines 4 | 5 | ## Options 6 | 7 | * `length`: `number`, (defaults to 300) 8 | 9 | ## Examples 10 | 11 | When enabled, the following are disallowed: 12 | 13 | ```scss 14 | /* 15 | * line count is represented along the 16 | * left hand side of the following example 17 | */ 18 | 1| .test { 19 | 2| color: red 20 | 3| } 21 | ===== 22 | ~ snip ~ 23 | ===== 24 | 299| .bar { 25 | 300| color: blue; 26 | 301| } 27 | ``` 28 | -------------------------------------------------------------------------------- /docs/rules/max-line-length.md: -------------------------------------------------------------------------------- 1 | # Max Line Length 2 | 3 | Rule `max-line-length` will enforce that lines do not exceed a max length / limit. 4 | 5 | ## Options 6 | 7 | * `length`: `number`, (defaults to 80) 8 | 9 | ## Examples 10 | 11 | When enabled, the following are disallowed: 12 | 13 | ```scss 14 | .really--long--class-name--that-unfortunately--isnt--very--succint--and-looks-stupid { 15 | color: red; 16 | } 17 | 18 | // ============================================================================== 19 | // 20 | // This comment is too long clearly, we should probably make sure we have a rule to 21 | // determine when we breach this length 22 | // 23 | // ============================================================================== 24 | ``` 25 | -------------------------------------------------------------------------------- /docs/rules/mixins-before-declarations.md: -------------------------------------------------------------------------------- 1 | # Mixins Before Declarations 2 | 3 | Rule `mixins-before-declarations` will enforce that mixins should be written before declarations in a ruleset. 4 | 5 | ## Options 6 | 7 | * `exclude`: `['breakpoint', 'mq']` (array of mixin names to be excluded from this rule) 8 | 9 | ## Examples 10 | 11 | When enabled, the following are allowed: 12 | 13 | ```scss 14 | .foo { 15 | @include bar; 16 | content: 'baz'; 17 | 18 | @include breakpoint(500px) { 19 | content: 'qux'; 20 | } 21 | 22 | @include mq(500px) { 23 | content: 'qux'; 24 | } 25 | } 26 | ``` 27 | 28 | When enabled, the following are disallowed: 29 | 30 | ```scss 31 | .foo { 32 | content: 'baz'; 33 | @include baz; 34 | } 35 | ``` 36 | -------------------------------------------------------------------------------- /docs/rules/nesting-depth.md: -------------------------------------------------------------------------------- 1 | # Nesting Depth 2 | 3 | Rule `nesting-depth` will enforce how deeply a selector can be nested. 4 | 5 | ## Options 6 | 7 | * `max-depth`: number (defaults to `2`) 8 | 9 | ## Examples 10 | 11 | When enabled (assuming `max-depth: 2`) the deepest element (`&:hover` and `&--modifier`) are at at depth 2. Any nested selector deeper is disallowed: 12 | 13 | ```scss 14 | .foo { 15 | .baz { 16 | &:hover { 17 | // Deepest Nest Allowed 18 | } 19 | } 20 | } 21 | 22 | .block { 23 | &__element { 24 | &--modifier { 25 | // Deepest Nest Allowed 26 | } 27 | } 28 | } 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/rules/no-attribute-selectors.md: -------------------------------------------------------------------------------- 1 | # No Attribute Selectors 2 | 3 | Rule `no-attribute-selectors` will warn against the use of attribute selectors. 4 | 5 | ## Examples 6 | 7 | When enabled, the following are disallowed: 8 | 9 | ```scss 10 | [autoplay] { 11 | content: 'foo'; 12 | } 13 | 14 | [lang=en] { 15 | content: 'bar'; 16 | } 17 | 18 | [lang~=en-us] { 19 | content: 'baz'; 20 | } 21 | 22 | [lang|=us] { 23 | content: 'qux'; 24 | } 25 | 26 | [href^="#"] { 27 | content: 'norf'; 28 | } 29 | 30 | [href$=".com"] { 31 | content: 'foo'; 32 | } 33 | 34 | [href*=news] { 35 | content: 'bar'; 36 | } 37 | ``` 38 | -------------------------------------------------------------------------------- /docs/rules/no-color-hex.md: -------------------------------------------------------------------------------- 1 | # No Color Hex 2 | 3 | Rule `no-color-hex` will disallow the use of hexadecimal colors 4 | 5 | ## Examples 6 | 7 | When enabled the following are disallowed. 8 | 9 | ```scss 10 | $foo-color: #456; 11 | 12 | .bar { 13 | background: linear-gradient(top, #3ff, #ddd); 14 | } 15 | 16 | .baz { 17 | color: #fff; 18 | } 19 | ``` 20 | 21 | When enabled the following are allowed: 22 | 23 | ```scss 24 | $foo-color: red; 25 | 26 | .bar { 27 | background: linear-gradient(top, blue, green); 28 | } 29 | 30 | .baz { 31 | color: white; 32 | } 33 | ``` 34 | -------------------------------------------------------------------------------- /docs/rules/no-color-keywords.md: -------------------------------------------------------------------------------- 1 | # Color Keyword 2 | 3 | Rule `no-color-keywords` will enforce the use of hexadecimal color values rather than literals. 4 | 5 | ## Examples 6 | 7 | When enabled the following are allowed: 8 | 9 | ```scss 10 | $new-red: #ff0000; 11 | 12 | .foo { 13 | color: #ff0000; 14 | } 15 | 16 | ``` 17 | 18 | When enabled the following are disallowed: 19 | 20 | ```scss 21 | $new-red: red; 22 | 23 | .foo { 24 | color: red; 25 | } 26 | ``` 27 | -------------------------------------------------------------------------------- /docs/rules/no-combinators.md: -------------------------------------------------------------------------------- 1 | # No Combinators 2 | 3 | Rule `no-combinators` will warn against the use of combinators. 4 | 5 | ## Examples 6 | 7 | When enabled, the following are disallowed: 8 | 9 | ```scss 10 | .foo > .bar { 11 | content: 'foo'; 12 | } 13 | 14 | .foo ~ .bar { 15 | content: 'bar'; 16 | } 17 | 18 | .foo + .bar { 19 | content: 'baz'; 20 | } 21 | 22 | .foo .bar { 23 | content: 'qux'; 24 | } 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/rules/no-css-comments.md: -------------------------------------------------------------------------------- 1 | # No CSS Comments 2 | 3 | Rule `no-css-comments` will enforce the use of Sass single-line comments and disallow CSS comments. Bang comments (`/*! */`, will be printed even in minified mode) are still allowed. 4 | 5 | ## Examples 6 | 7 | When enabled the following are allowed: 8 | 9 | ```scss 10 | 11 | // This is a good comment 12 | 13 | // ========= 14 | // This is a good comment 15 | // ========= 16 | 17 | ////////////////// 18 | // This is a good comment 19 | ////////////////// 20 | 21 | /*! This is a good bang comment */ 22 | 23 | /*! 24 | * This is a good bang comment 25 | **/ 26 | ``` 27 | 28 | When enabled the following are disallowed: 29 | 30 | ```scss 31 | 32 | /* This comment will appear in your compiled css */ 33 | 34 | /* 35 | * Mulitline comments are bad 36 | */ 37 | ``` 38 | -------------------------------------------------------------------------------- /docs/rules/no-debug.md: -------------------------------------------------------------------------------- 1 | # No Debug 2 | 3 | Rule `no-debug` will enforce that `@debug` statements are not allowed to be used. 4 | 5 | ## Examples 6 | 7 | When enabled, the following are disallowed: 8 | 9 | ```scss 10 | @debug 'foo'; 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/rules/no-disallowed-properties.md: -------------------------------------------------------------------------------- 1 | # No Disallowed Properties 2 | 3 | Rule `no-disallowed-properties` will warn against the use of certain properties. 4 | 5 | ## Options 6 | 7 | * `properties`: `[array of disallowed properties]` (defaults to empty array `[]`). 8 | 9 | ## Examples 10 | 11 | When `properties` contains a property value of `z-index` as shown below: 12 | 13 | ```yaml 14 | no-disallowed-properties: 15 | - 1 16 | - 17 | 'properties': 18 | - 'z-index' 19 | ``` 20 | 21 | The following would not be allowed: 22 | 23 | ```scss 24 | 25 | // z-index property is not allowed 26 | .foo { 27 | z-index: 10; 28 | } 29 | 30 | ``` 31 | -------------------------------------------------------------------------------- /docs/rules/no-disallowed-property-values.md: -------------------------------------------------------------------------------- 1 | # No Disallowed Property Values 2 | 3 | Rule `no-disallowed-property-values` will warn against the use of certain values for properties. Either a single string can be specified for a single disallowed value, or an array of disallowed property values. 4 | 5 | ## Options 6 | 7 | * `properties`: `{dictionary of properties mapped to string or array of strings representing values}` (defaults to empty dictionary `{}`). 8 | 9 | ## Examples 10 | 11 | When `properties` contains a the following options for disallowed values of `text-transform` and `white-space`: 12 | 13 | ```yaml 14 | no-disallowed-property-values: 15 | - 1 16 | - 17 | properties: 18 | text-transform: capitalize 19 | white-space: ['pre', 'pre-wrap'] 20 | ``` 21 | 22 | The following would not be allowed: 23 | 24 | ```scss 25 | 26 | // the capitalize value for text-transform is not allowed 27 | .foo { 28 | text-transform: capitalize; 29 | } 30 | 31 | // the pre and pre-wrap values for white-space are not allowed 32 | .bar { 33 | white-space: pre; 34 | } 35 | .baz { 36 | white-space: pre-wrap; 37 | } 38 | ``` 39 | -------------------------------------------------------------------------------- /docs/rules/no-empty-rulesets.md: -------------------------------------------------------------------------------- 1 | # No Empty Rulesets 2 | 3 | Rule `no-empty-rulesets` will enforce that rulesets are not empty. 4 | 5 | ## Examples 6 | 7 | When enabled, the following are disallowed: 8 | 9 | ```scss 10 | .foo { 11 | 12 | } 13 | 14 | .bar { 15 | content: 'baz'; 16 | 17 | .qux {} 18 | } 19 | 20 | .waldo {} 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/rules/no-extends.md: -------------------------------------------------------------------------------- 1 | # No Extends 2 | 3 | Rule `no-extends` will enforce that extends are not allowed to be used. 4 | 5 | ## Examples 6 | 7 | When enabled, the following are disallowed: 8 | 9 | ```scss 10 | .foo { 11 | @extend %bar; 12 | @extend .bar; 13 | @extend #bar; 14 | } 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/rules/no-ids.md: -------------------------------------------------------------------------------- 1 | # No IDs 2 | 3 | Rule `no-ids` will enforce that ID selectors are not allowed to be used. 4 | 5 | ## Examples 6 | 7 | When enabled, the following are disallowed: 8 | 9 | ```scss 10 | #foo { 11 | content: 'bar'; 12 | } 13 | ``` 14 | -------------------------------------------------------------------------------- /docs/rules/no-important.md: -------------------------------------------------------------------------------- 1 | # No Important 2 | 3 | Rule `no-important` will enforce that important declarations are not allowed to be used. 4 | 5 | ## Examples 6 | 7 | When enabled, the following are disallowed: 8 | 9 | ```scss 10 | .foo { 11 | content: 'bar' !important; 12 | } 13 | ``` 14 | -------------------------------------------------------------------------------- /docs/rules/no-invalid-hex.md: -------------------------------------------------------------------------------- 1 | # No Invalid Hex 2 | 3 | Rule `no-invalid-hex` will enforce that only valid of hexadecimal values are written. 4 | 5 | ## Examples 6 | 7 | When enabled any invalid hexadecimal characters will generate a warning/error: 8 | 9 | ```scss 10 | 11 | // must be 3 or 6 characters 12 | $invalid-long: #1234567; 13 | $invalid-med: #1234; 14 | $invalid-short: #12; 15 | $invalid-letters-long: #abcdefg; 16 | $invalid-letters-med: #abcd; 17 | $invalid-letters-short: #ab; 18 | $invalid-mixed-long: #1bcdefg; 19 | $invalid-mixed-med: #1bcd; 20 | $invalid-mixed-short: #1b; 21 | $invalid-mixed-letters-long: #abcdef7; 22 | $invalid-mixed-letters-med: #abc4; 23 | $invalid-mixed-letters-short: #a1; 24 | 25 | // mustn't contain invalid characters 26 | $invalid-character-map: ( 27 | invalid-characters-upper-letters: #GHIJKL, 28 | invalid-characters-upper-letters-short: #GHI, 29 | even-more-invalid-map: ( 30 | invalid-characters-lower-letters-short: #ghijkl, 31 | invalid-characters-lower-letters-short: #ghi 32 | ) 33 | ); 34 | ``` 35 | -------------------------------------------------------------------------------- /docs/rules/no-trailing-whitespace.md: -------------------------------------------------------------------------------- 1 | # No Trailing Whitespace 2 | 3 | Rule `no-trailing-whitespace` will enforce that trailing whitespace is not allowed. 4 | 5 | ## Examples 6 | 7 | When enabled, the following are disallowed (\s denotes spaces or tabs): 8 | 9 | ```scss 10 | .foo {\s 11 | margin: 1.5rem; 12 | } 13 | 14 | .foo { 15 | margin: .5rem;\s 16 | } 17 | 18 | .foo { 19 | margin: .4rem; 20 | }\s 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/rules/no-trailing-zero.md: -------------------------------------------------------------------------------- 1 | # No Trailing Zero 2 | 3 | Rule `no-trailing-zero` will enforce that trailing zeros are not allowed. 4 | 5 | ## Examples 6 | 7 | When enabled, the following are disallowed: 8 | 9 | ```scss 10 | .foo { 11 | margin: 1.500rem; 12 | } 13 | 14 | .foo { 15 | margin: .500rem; 16 | } 17 | 18 | .foo { 19 | margin: 0.2500rem; 20 | } 21 | 22 | .foo { 23 | margin: 4.0rem; 24 | } 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/rules/no-transition-all.md: -------------------------------------------------------------------------------- 1 | # No Transition All 2 | 3 | Rule `no-transition-all` will enforce whether the keyword `all` can be used with the `transition` or `transition-property` property. 4 | 5 | ## Examples 6 | 7 | When enabled the following are disallowed 8 | 9 | ```scss 10 | .foo { 11 | transition: all 2s; 12 | } 13 | 14 | .bar { 15 | transition-property: all 2s; 16 | } 17 | 18 | .quz { 19 | -webkit-transition: all 2s, height 2s, background-color 2s, -webkit-transform 2s; 20 | } 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/rules/no-universal-selectors.md: -------------------------------------------------------------------------------- 1 | # No Universal Selectors 2 | 3 | Rule `no-universal-selectors` will warn against the use of `*` (universal) selectors. 4 | 5 | ## Examples 6 | 7 | When enabled, the following are disallowed: 8 | 9 | ```scss 10 | * { 11 | content: 'foo'; 12 | } 13 | 14 | * [lang^=en] { 15 | content: 'bar'; 16 | } 17 | 18 | *.warning { 19 | content: 'baz'; 20 | } 21 | 22 | *#maincontent { 23 | content: 'qux'; 24 | } 25 | 26 | *:before, 27 | *:after { 28 | content: 'norf'; 29 | } 30 | ``` 31 | -------------------------------------------------------------------------------- /docs/rules/no-url-domains.md: -------------------------------------------------------------------------------- 1 | # No Url Domains 2 | 3 | Rule `no-url-domains` will enforce that domains are not used within urls. 4 | 5 | ## Examples 6 | 7 | When enabled, the following are allowed: 8 | 9 | ```scss 10 | .foo { 11 | background-image: url('/img/bar.png'); 12 | } 13 | 14 | .foo { 15 | background-image: url('img/bar.png'); 16 | } 17 | 18 | .foo { 19 | background-image: url('bar.png'); 20 | } 21 | ``` 22 | 23 | When enabled, the following are disallowed: 24 | 25 | ```scss 26 | .foo { 27 | background-image: url('https://foo.com/img/bar.png'); 28 | } 29 | 30 | .foo { 31 | background-image: url('http://foo.com/img/bar.png'); 32 | } 33 | 34 | .foo { 35 | background-image: url('//foo.com/img/bar.png'); 36 | } 37 | ``` 38 | -------------------------------------------------------------------------------- /docs/rules/no-warn.md: -------------------------------------------------------------------------------- 1 | # No Warn 2 | 3 | Rule `no-warn` will enforce that `@warn` statements are not allowed to be used. 4 | 5 | ## Examples 6 | 7 | When enabled, the following are disallowed: 8 | 9 | ```scss 10 | @warn 'foo'; 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/rules/one-declaration-per-line.md: -------------------------------------------------------------------------------- 1 | # One Declaration Per Line 2 | 3 | Rule `one-declaration-per-line` will enforce that new declarations must begin on new lines. 4 | 5 | ## Examples 6 | 7 | When enabled, the following are allowed: 8 | 9 | ```scss 10 | .foo { 11 | content: 'baz'; 12 | content: 'qux'; 13 | } 14 | ``` 15 | 16 | When enabled, the following are disallowed: 17 | 18 | ```scss 19 | .foo {content: 'baz', content: 'qux'}; 20 | 21 | .foo { 22 | content: 'baz'; content: 'qux'; 23 | } 24 | ``` 25 | -------------------------------------------------------------------------------- /docs/rules/placeholder-in-extend.md: -------------------------------------------------------------------------------- 1 | # Placeholder in Extend 2 | 3 | Rule `placeholder-in-extend` will enforce whether extends should only include placeholder selectors. 4 | 5 | ## Examples 6 | 7 | When enabled, the following are allowed: 8 | 9 | ```scss 10 | .foo { 11 | @extend %bar; 12 | @extend .baz%qux; 13 | } 14 | ``` 15 | 16 | When enabled, the following are disallowed: 17 | 18 | ```scss 19 | .foo { 20 | @extend .bar; 21 | @extend #baz; 22 | } 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/rules/property-units.md: -------------------------------------------------------------------------------- 1 | # Property Units 2 | 3 | Rule `property-units` will disallow the use of units not specified in `global` or `per-property`. Units specified `per-property` will override the `global` units for that property. 4 | 5 | ## Options 6 | 7 | * `global`: `['em', 'px', 'rem', etc]` defaults to [] or all units allowed 8 | * `per-property`: `{ width: ['rem', 'px', etc], height: ['rem', 'px', etc], }` defaults to {} or no property-specific units 9 | 10 | ## Examples 11 | 12 | When enabled, `global` is set to `['px']`, and `per-property` is set to `{ width: ['rem'] }` the following are disallowed. 13 | 14 | ```scss 15 | .literal { 16 | height: 3rem; 17 | } 18 | 19 | .literal-property { 20 | width: 3px; 21 | } 22 | 23 | .box-shadow { 24 | box-shadow: 1em 1em black, 1em 1em black; 25 | } 26 | 27 | .background { 28 | background: 1em solid white; 29 | } 30 | 31 | ``` 32 | 33 | When enabled, `global` is set to `['em']`, and `per-property` is set to `{ width: ['rem'] }` the following are allowed. 34 | 35 | ```scss 36 | 37 | .variable { 38 | width: $sizes.small; 39 | } 40 | 41 | .function { 42 | color: test(2px); 43 | } 44 | 45 | // using literals as property names 46 | $sizes: ( 47 | small: 2px 48 | ); 49 | ``` 50 | -------------------------------------------------------------------------------- /docs/rules/pseudo-element.md: -------------------------------------------------------------------------------- 1 | # Pseudo-element 2 | 3 | Rule `pseudo-element` will enforce that: 4 | 5 | * Pseudo-**elements** must start with **double colons**. 6 | * Pseudo-**classes** must start with **single colon**. 7 | 8 | ## Examples 9 | 10 | When enabled, the following are allowed: 11 | 12 | ```scss 13 | .foo::before { 14 | content: "bar"; 15 | } 16 | 17 | .foo:hover { 18 | content: "bar"; 19 | } 20 | ``` 21 | 22 | When enabled, the following are disallowed: 23 | 24 | ```scss 25 | .foo:before { 26 | content: "bar"; 27 | } 28 | 29 | .foo::hover { 30 | content: "bar"; 31 | } 32 | ``` 33 | -------------------------------------------------------------------------------- /docs/rules/quotes.md: -------------------------------------------------------------------------------- 1 | # Quotes 2 | 3 | Rule `quotes` will enforce whether single quotes (`''`) or double quotes (`""`) should be used for all strings. 4 | 5 | ## Options 6 | 7 | * `style`: `single`/`double` (defaults to `single`) 8 | 9 | ## Examples 10 | 11 | When `style: single`, the following are allowed. When `style: double`, the following are disallowed: 12 | 13 | ```scss 14 | .foo { 15 | content: 'bar'; 16 | } 17 | ``` 18 | 19 | When `style: double`, the following are allowed. When `style: single`, the following are disallowed: 20 | 21 | ```scss 22 | .foo { 23 | content: "bar"; 24 | } 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/rules/single-line-per-selector.md: -------------------------------------------------------------------------------- 1 | # Single Line Per Selector 2 | 3 | Rule `single-line-per-selector` will enforce whether selectors should be placed on a new line. 4 | 5 | ## Examples 6 | 7 | When enabled, the following are allowed: 8 | 9 | ```scss 10 | .foo, 11 | .bar { 12 | content: 'baz'; 13 | } 14 | ``` 15 | 16 | When enabled, the following are disallowed: 17 | 18 | ```scss 19 | .foo, .bar { 20 | content: 'baz'; 21 | } 22 | ``` 23 | -------------------------------------------------------------------------------- /docs/rules/space-after-bang.md: -------------------------------------------------------------------------------- 1 | # Space After Bang 2 | 3 | Rule `space-after-bang` will enforce whether or not a space should be included after a bang (`!`). 4 | 5 | ## Options 6 | 7 | * `include`: `true`/`false` (defaults to `false`) 8 | 9 | ## Examples 10 | 11 | When `include: false`, the following are allowed. When `include: true`, the following are disallowed: 12 | 13 | ```scss 14 | .foo { 15 | content: 'bar' !important; 16 | } 17 | ``` 18 | 19 | When `include: true`, the following are allowed. When `include: false`, the following are disallowed: 20 | 21 | ```scss 22 | .foo { 23 | content: 'bar' ! important; 24 | } 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/rules/space-after-colon.md: -------------------------------------------------------------------------------- 1 | # Space After Colon 2 | 3 | Rule `space-after-colon` will enforce whether or not a space should be included after a colon (`:`). 4 | 5 | ## Options 6 | 7 | * `include`: `true`/`false` (defaults to `true`) 8 | 9 | ## Examples 10 | 11 | When `include: true`, the following are allowed. When `include: false`, the following are disallowed: 12 | 13 | ```scss 14 | .foo { 15 | content: 'bar'; 16 | } 17 | ``` 18 | 19 | When `include: false`, the following are allowed. When `include: true`, the following are disallowed: 20 | 21 | ```scss 22 | .foo { 23 | content:'bar'; 24 | } 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/rules/space-after-comma.md: -------------------------------------------------------------------------------- 1 | # Space After Comma 2 | 3 | Rule `space-after-comma` will enforce whether or not a space should be included after a comma (`,`). 4 | 5 | ## Options 6 | 7 | * `include`: `true`/`false` (defaults to `true`) 8 | 9 | ## Examples 10 | 11 | When `include: true`, the following are allowed. When `include: false`, the following are disallowed: 12 | 13 | ```scss 14 | .foo { 15 | @include baz('foo', 'bar'); 16 | 17 | box-shadow: 1px 1px black, 1px 1px black; 18 | } 19 | ``` 20 | 21 | When `include: false`, the following are allowed. When `include: true`, the following are disallowed: 22 | 23 | ```scss 24 | .foo { 25 | @include baz('foo','bar'); 26 | 27 | box-shadow: 1px 1px black,1px 1px black; 28 | } 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/rules/space-before-bang.md: -------------------------------------------------------------------------------- 1 | # Space Before Bang 2 | 3 | Rule `space-before-bang` will enforce whether or not a space should be included before a bang (`!`). 4 | 5 | ## Options 6 | 7 | * `include`: `true`/`false` (defaults to `true`) 8 | 9 | ## Examples 10 | 11 | When `include: true`, the following are allowed. When `include: false`, the following are disallowed: 12 | 13 | ```scss 14 | .foo { 15 | content: 'bar' !important; 16 | } 17 | ``` 18 | 19 | When `include: false`, the following are allowed. When `include: true`, the following are disallowed: 20 | 21 | ```scss 22 | .foo { 23 | content: 'bar'!important; 24 | } 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/rules/space-before-brace.md: -------------------------------------------------------------------------------- 1 | # Space Before Brace 2 | 3 | Rule `space-before-brace` will enforce whether or not a space should be included before a brace (`{`). 4 | 5 | ## Options 6 | 7 | * `include`: `true`/`false` (defaults to `true`) 8 | 9 | ## Examples 10 | 11 | When `include: true`, the following are allowed. When `include: false`, the following are disallowed: 12 | 13 | ```scss 14 | .foo { 15 | content: 'bar'; 16 | 17 | @include breakpoint { 18 | content: 'baz'; 19 | } 20 | } 21 | 22 | @mixin foo { 23 | content: 'bar'; 24 | } 25 | ``` 26 | 27 | When `include: false`, the following are allowed. When `include: true`, the following are disallowed: 28 | 29 | ```scss 30 | .foo{ 31 | content: 'bar'; 32 | 33 | @include breakpoint{ 34 | content: 'baz'; 35 | } 36 | } 37 | 38 | @mixin foo{ 39 | content: 'bar'; 40 | } 41 | ``` 42 | -------------------------------------------------------------------------------- /docs/rules/space-before-colon.md: -------------------------------------------------------------------------------- 1 | # Space Before Colon 2 | 3 | Rule `space-before-colon` will enforce whether or not a space should be included before a colon (`:`). 4 | 5 | ## Options 6 | 7 | * `include`: `true`/`false` (defaults to `false`) 8 | 9 | ## Examples 10 | 11 | When `include: false`, the following are allowed. When `include: true`, the following are disallowed: 12 | 13 | ```scss 14 | .foo { 15 | content: 'bar'; 16 | } 17 | ``` 18 | 19 | When `include: true`, the following are allowed. When `include: false`, the following are disallowed: 20 | 21 | ```scss 22 | .foo { 23 | content :'bar'; 24 | } 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/rules/space-between-parens.md: -------------------------------------------------------------------------------- 1 | # Space Between Parens 2 | 3 | Rule `space-between-parens` will enforce whether or not a space should be included before the first item and after the last item inside parenthesis (`()`). 4 | 5 | ## Options 6 | 7 | * `include`: `true`/`false` (defaults to `false`) 8 | 9 | ## Examples 10 | 11 | When `include: false`, the following are allowed. When `include: true`, the following are disallowed: 12 | 13 | ```scss 14 | @function foo($bar) { 15 | @return $bar; 16 | } 17 | 18 | @mixin bar($baz) { 19 | content: $baz; 20 | } 21 | 22 | .foo { 23 | @include bar('Hello'); 24 | content: foo('bar'); 25 | width: calc(100% - 10px); 26 | } 27 | ``` 28 | 29 | When `include: true`, the following are allowed. When `include: false`, the following are disallowed: 30 | 31 | ```scss 32 | @function foo( $bar ) { 33 | @return $bar; 34 | } 35 | 36 | @mixin bar($baz ) { 37 | content: $baz; 38 | } 39 | 40 | .foo { 41 | @include bar( 'Hello' ); 42 | content: foo( 'bar'); 43 | width: calc( 100% - 10px); 44 | } 45 | ``` 46 | -------------------------------------------------------------------------------- /docs/rules/trailing-semicolon.md: -------------------------------------------------------------------------------- 1 | # Trailing Semicolon 2 | 3 | Rule `trailing-semicolon` will enforce whether the last declaration in a block should include a semicolon (`;`) or not (`.sass` syntax excluded). 4 | 5 | ## Options 6 | 7 | * `include`: `true`/`false` (defaults to `true`) 8 | 9 | ## Examples 10 | 11 | When `include: true`, the following are allowed. When `include: false`, the following are disallowed: 12 | 13 | ```scss 14 | .foo { 15 | content: 'bar'; 16 | content: 'baz'; 17 | 18 | .waldo { 19 | content: 'where'; 20 | } 21 | } 22 | ``` 23 | 24 | When `include: false`, the following are allowed. When `include: true`, the following are disallowed: 25 | 26 | ```scss 27 | .foo { 28 | content: 'bar'; 29 | content: 'baz' 30 | 31 | .waldo { 32 | content: 'where' 33 | } 34 | } 35 | ``` 36 | -------------------------------------------------------------------------------- /docs/rules/url-quotes.md: -------------------------------------------------------------------------------- 1 | # URL Quotes 2 | 3 | Rule `url-quotes` will enforce that URLs are wrapped in quotes. 4 | 5 | ## Examples 6 | 7 | When enabled, the following are allowed: 8 | 9 | ```scss 10 | .foo { 11 | background-image: url('foo.png'); 12 | } 13 | 14 | .qux { 15 | background-image: url('bar/' + $foo); 16 | } 17 | 18 | ``` 19 | 20 | When enabled, the following are disallowed: 21 | 22 | ```scss 23 | .bar { 24 | background-image: url(foo.png); 25 | } 26 | 27 | .norf { 28 | background-image: url(bar/ + $foo); 29 | } 30 | 31 | ``` 32 | -------------------------------------------------------------------------------- /docs/rules/zero-unit.md: -------------------------------------------------------------------------------- 1 | # Zero Unit 2 | 3 | Rule `zero-unit` will enforce whether or not values of `0` used for length should be unitless. 4 | 5 | ## Options 6 | 7 | * `include`: `true`/`false` (defaults to `false`) 8 | 9 | ## Examples 10 | 11 | When `include: false`, the following are allowed. When `include: true`, the following are disallowed: 12 | 13 | ```scss 14 | .foo { 15 | margin: 0; 16 | } 17 | 18 | .bar { 19 | padding: 5px 0 0; 20 | } 21 | ``` 22 | 23 | When `include: true`, the following are allowed. When `include: false`, the following are disallowed: 24 | 25 | ```scss 26 | .foo { 27 | margin: 0px; 28 | } 29 | 30 | .bar { 31 | padding: 5px 0px 0px; 32 | } 33 | ``` 34 | -------------------------------------------------------------------------------- /docs/sass-lint.yml: -------------------------------------------------------------------------------- 1 | ######################### 2 | ## Sample Sass Lint File 3 | ######################### 4 | # Linter Options 5 | options: 6 | # Don't merge default rules 7 | merge-default-rules: false 8 | # Set the formatter to 'html' 9 | formatter: html 10 | # Output file instead of logging results 11 | output-file: 'linters/sass-lint.html' 12 | # Raise an error if more than 50 warnings are generated 13 | max-warnings: 50 14 | # File Options 15 | files: 16 | include: 'sass/**/*.s+(a|c)ss' 17 | ignore: 18 | - 'sass/vendor/**/*.*' 19 | # Rule Configuration 20 | rules: 21 | extends-before-mixins: 2 22 | extends-before-declarations: 2 23 | placeholder-in-extend: 2 24 | mixins-before-declarations: 25 | - 2 26 | - 27 | exclude: 28 | - breakpoint 29 | - mq 30 | 31 | no-warn: 1 32 | no-debug: 1 33 | no-ids: 2 34 | no-important: 2 35 | hex-notation: 36 | - 2 37 | - 38 | style: uppercase 39 | indentation: 40 | - 2 41 | - 42 | size: 2 43 | property-sort-order: 44 | - 1 45 | - 46 | order: 47 | - display 48 | - margin 49 | ignore-custom-properties: true 50 | variable-for-property: 51 | - 2 52 | - 53 | properties: 54 | - margin 55 | - content 56 | -------------------------------------------------------------------------------- /lib/exceptions.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var util = require('util'); 4 | 5 | module.exports = { 6 | SassLintFailureError: function (message) { 7 | Error.captureStackTrace(this, this.constructor); 8 | this.name = 'SassLintFailureError'; 9 | this.message = message; 10 | }, 11 | MaxWarningsExceededError: function (message) { 12 | Error.captureStackTrace(this, this.constructor); 13 | this.name = 'MaxWarningsExceededError'; 14 | this.message = message; 15 | } 16 | }; 17 | 18 | util.inherits(module.exports.SassLintFailureError, Error); 19 | util.inherits(module.exports.MaxWarningsExceededError, Error); 20 | -------------------------------------------------------------------------------- /lib/format/formatters/html-template-message.html: -------------------------------------------------------------------------------- 1 | 2 | <%= lineNumber %>:<%= columnNumber %> 3 | <%= severityName %> 4 | <%- message %> 5 | 6 | <%= ruleId %> 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib/format/formatters/html-template-result.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | [+] <%- filePath %> 4 | <%- summary %> 5 | 6 | 7 | -------------------------------------------------------------------------------- /lib/format/formatters/json.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview JSON reporter 3 | * @author Burak Yigit Kaya aka BYK 4 | * 5 | * Updated for use with sass-lint under MIT licence 6 | * @license https://github.com/sasstools/sass-lint/blob/master/lib/format/LICENSE 7 | */ 8 | 9 | 'use strict'; 10 | 11 | //------------------------------------------------------------------------------ 12 | // Public Interface 13 | //------------------------------------------------------------------------------ 14 | 15 | module.exports = function (results) { 16 | return JSON.stringify(results); 17 | }; 18 | -------------------------------------------------------------------------------- /lib/format/formatters/unix.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview unix-style formatter. 3 | * @author oshi-shinobu 4 | * 5 | * Updated for use with sass-lint under MIT licence 6 | * @license https://github.com/sasstools/sass-lint/blob/master/lib/format/LICENSE 7 | */ 8 | 9 | 'use strict'; 10 | 11 | const getMessageType = require('../../helpers').getMessageType; 12 | 13 | //------------------------------------------------------------------------------ 14 | // Public Interface 15 | //------------------------------------------------------------------------------ 16 | 17 | module.exports = function (results) { 18 | 19 | let output = '', 20 | total = 0; 21 | 22 | results.forEach(result => { 23 | 24 | const messages = result.messages; 25 | 26 | total += messages.length; 27 | 28 | messages.forEach(message => { 29 | 30 | output += `${result.filePath}:`; 31 | output += `${message.line || 0}:`; 32 | output += `${message.column || 0}:`; 33 | output += ` ${message.message} `; 34 | output += `[${getMessageType(message)}${message.ruleId ? `/${message.ruleId}` : ''}]`; 35 | output += '\n'; 36 | }); 37 | }); 38 | 39 | if (total > 0) { 40 | output += `\n${total} problem${total !== 1 ? 's' : ''}`; 41 | } 42 | 43 | return output; 44 | }; 45 | -------------------------------------------------------------------------------- /lib/groot.js: -------------------------------------------------------------------------------- 1 | ////////////////////////////// 2 | // Tree Abstraction 3 | ////////////////////////////// 4 | 'use strict'; 5 | 6 | var gonzales = require('gonzales-pe'); 7 | var matter = require('gray-matter'); 8 | 9 | module.exports = function (input, syntax, filename) { 10 | var tree; 11 | var result = matter(input, {}); 12 | var text = result.content; 13 | 14 | if (result.matter) { 15 | var emptyLines = new Array(result.matter.split('\n').length + 2).join('\n'); 16 | text = emptyLines + result.content; 17 | } 18 | 19 | try { 20 | tree = gonzales.parse(text, { 21 | 'syntax': syntax 22 | }); 23 | } 24 | catch (e) { 25 | throw { 26 | message: e.message, 27 | file: filename, 28 | line: e.line 29 | }; 30 | } 31 | 32 | if (typeof tree === 'undefined') { 33 | throw { 34 | message: 'Undefined tree', 35 | file: filename, 36 | text: text.toString(), 37 | tree: tree.toString() 38 | }; 39 | } 40 | 41 | return tree; 42 | }; 43 | -------------------------------------------------------------------------------- /lib/rules/attribute-quotes.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | 5 | module.exports = { 6 | 'name': 'attribute-quotes', 7 | 'defaults': { 8 | 'include': true 9 | }, 10 | 'detect': function (ast, parser) { 11 | var result = []; 12 | 13 | ast.traverseByType('attributeValue', function (item) { 14 | if (item.content[0].is('string') && !parser.options.include) { 15 | result = helpers.addUnique(result, { 16 | 'ruleId': parser.rule.name, 17 | 'line': item.start.line, 18 | 'column': item.start.column, 19 | 'message': 'Attribute values should not be surrounded by quotes', 20 | 'severity': parser.severity 21 | }); 22 | } 23 | else if (item.content[0].is('ident') && parser.options.include) { 24 | result = helpers.addUnique(result, { 25 | 'ruleId': parser.rule.name, 26 | 'line': item.start.line, 27 | 'column': item.start.column, 28 | 'message': 'Attribute values should be surrounded by quotes', 29 | 'severity': parser.severity 30 | }); 31 | } 32 | }); 33 | 34 | return result; 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /lib/rules/max-file-line-count.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | 5 | module.exports = { 6 | 'name': 'max-file-line-count', 7 | 'defaults': { 8 | length: 300 9 | }, 10 | 'detect': function (ast, parser) { 11 | var result = []; 12 | 13 | if (ast.end.line > parser.options.length) { 14 | result = helpers.addUnique(result, { 15 | 'ruleId': parser.rule.name, 16 | 'line': ast.end.line, 17 | 'column': 0, 18 | 'message': 'This file has ' + ast.end.line + ' lines, which exceeds the maximum of ' + parser.options.length + ' lines allowed.', 19 | 'severity': parser.severity 20 | }); 21 | } 22 | 23 | return result; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /lib/rules/max-line-length.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | 5 | module.exports = { 6 | 'name': 'max-line-length', 7 | 'defaults': { 8 | length: 80 9 | }, 10 | 'detect': function (ast, parser) { 11 | var result = []; 12 | 13 | ast.traverseByType('space', function (space) { 14 | var lineLength = 0; 15 | if (helpers.hasEOL(space.content)) { 16 | lineLength = space.start.column - 1; 17 | } 18 | 19 | if (lineLength > parser.options.length) { 20 | result = helpers.addUnique(result, { 21 | 'ruleId': parser.rule.name, 22 | 'severity': parser.severity, 23 | 'line': space.start.line, 24 | 'column': 0, 25 | 'message': 'line ' + space.start.line + ' exceeds the maximum line length of ' + parser.options.length 26 | }); 27 | } 28 | }); 29 | 30 | return result; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /lib/rules/no-attribute-selectors.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | 5 | module.exports = { 6 | 'name': 'no-attribute-selectors', 7 | 'defaults': {}, 8 | 'detect': function (ast, parser) { 9 | var result = []; 10 | 11 | ast.traverseByType('attributeSelector', function (item) { 12 | result = helpers.addUnique(result, { 13 | 'ruleId': parser.rule.name, 14 | 'line': item.start.line, 15 | 'column': item.start.column, 16 | 'message': 'Attribute selectors are not allowed', 17 | 'severity': parser.severity 18 | }); 19 | }); 20 | 21 | return result; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /lib/rules/no-color-hex.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | 5 | module.exports = { 6 | 'name': 'no-color-hex', 7 | 'defaults': {}, 8 | 'detect': function (ast, parser) { 9 | var result = []; 10 | 11 | ast.traverseByType('color', function (value) { 12 | result = helpers.addUnique(result, { 13 | 'ruleId': parser.rule.name, 14 | 'line': value.start.line, 15 | 'column': value.start.column, 16 | 'message': 'Hexadecimal colors should not be used', 17 | 'severity': parser.severity 18 | }); 19 | }); 20 | return result; 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /lib/rules/no-css-comments.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | 5 | module.exports = { 6 | 'name': 'no-css-comments', 7 | 'defaults': {}, 8 | 'detect': function (ast, parser) { 9 | var result = []; 10 | 11 | ast.traverseByType('multilineComment', function (node) { 12 | if (node.content.charAt(0) !== '!') { 13 | result = helpers.addUnique(result, { 14 | 'ruleId': parser.rule.name, 15 | 'line': node.start.line, 16 | 'column': node.start.column, 17 | 'message': 'Multiline style comments should not be used', 18 | 'severity': parser.severity 19 | }); 20 | } 21 | }); 22 | return result; 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /lib/rules/no-debug.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | 5 | module.exports = { 6 | 'name': 'no-debug', 7 | 'defaults': {}, 8 | 'detect': function (ast, parser) { 9 | var result = []; 10 | 11 | ast.traverseByType('atkeyword', function (keyword) { 12 | keyword.traverse(function (item) { 13 | if (item.content === 'debug') { 14 | result = helpers.addUnique(result, { 15 | 'ruleId': parser.rule.name, 16 | 'line': item.start.line, 17 | 'column': item.start.column, 18 | 'message': '@debug not allowed', 19 | 'severity': parser.severity 20 | }); 21 | } 22 | }); 23 | }); 24 | 25 | return result; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /lib/rules/no-disallowed-properties.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | 5 | module.exports = { 6 | 'name': 'no-disallowed-properties', 7 | 'defaults': { 8 | 'properties': [] 9 | }, 10 | 'detect': function (ast, parser) { 11 | var result = []; 12 | 13 | ast.traverseByType('property', function (node) { 14 | var first = node.first(); 15 | if (!first.is('ident') || parser.options.properties.indexOf(first.content) === -1) { 16 | return; 17 | } 18 | result = helpers.addUnique(result, { 19 | 'ruleId': parser.rule.name, 20 | 'line': node.start.line, 21 | 'column': node.start.column, 22 | 'message': 'Property `' + first.content + '` should not be used', 23 | 'severity': parser.severity 24 | }); 25 | }); 26 | return result; 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /lib/rules/no-extends.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | 5 | module.exports = { 6 | 'name': 'no-extends', 7 | 'defaults': {}, 8 | 'detect': function (ast, parser) { 9 | var result = []; 10 | 11 | ast.traverseByType('atkeyword', function (keyword) { 12 | keyword.traverse(function (item) { 13 | if (item.content === 'extend') { 14 | result = helpers.addUnique(result, { 15 | 'ruleId': parser.rule.name, 16 | 'line': item.start.line, 17 | 'column': item.start.column, 18 | 'message': '@extend not allowed', 19 | 'severity': parser.severity 20 | }); 21 | } 22 | }); 23 | }); 24 | 25 | return result; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /lib/rules/no-ids.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | 5 | module.exports = { 6 | 'name': 'no-ids', 7 | 'defaults': {}, 8 | 'detect': function (ast, parser) { 9 | var result = []; 10 | 11 | ast.traverseByType('id', function (id) { 12 | result = helpers.addUnique(result, { 13 | 'ruleId': parser.rule.name, 14 | 'line': id.start.line, 15 | 'column': id.start.column, 16 | 'message': 'ID selectors not allowed', 17 | 'severity': parser.severity 18 | }); 19 | }); 20 | 21 | return result; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /lib/rules/no-important.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | 5 | module.exports = { 6 | 'name': 'no-important', 7 | 'defaults': {}, 8 | 'detect': function (ast, parser) { 9 | var result = []; 10 | 11 | ast.traverseByType('important', function (item) { 12 | result = helpers.addUnique(result, { 13 | 'ruleId': parser.rule.name, 14 | 'line': item.start.line, 15 | 'column': item.start.column, 16 | 'message': '!important not allowed', 17 | 'severity': parser.severity 18 | }); 19 | }); 20 | 21 | return result; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /lib/rules/no-invalid-hex.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | 5 | module.exports = { 6 | 'name': 'no-invalid-hex', 7 | 'defaults': {}, 8 | 'detect': function (ast, parser) { 9 | var result = []; 10 | 11 | ast.traverseByType('color', function (value) { 12 | if (!helpers.isValidHex(value.content)) { 13 | result = helpers.addUnique(result, { 14 | 'ruleId': parser.rule.name, 15 | 'line': value.start.line, 16 | 'column': value.start.column, 17 | 'message': 'Hexadecimal values must be a valid format', 18 | 'severity': parser.severity 19 | }); 20 | } 21 | }); 22 | return result; 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /lib/rules/no-trailing-whitespace.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | 5 | module.exports = { 6 | 'name': 'no-trailing-whitespace', 7 | 'defaults': {}, 8 | 'detect': function (ast, parser) { 9 | var result = []; 10 | var trailing = (/( |\t)+\n/); 11 | var trailingCRLF = (/( |\t)+\r\n/); 12 | 13 | ast.traverseByType('space', function (space, i, parent) { 14 | var content = space.content; 15 | var nextIndex = i + 1; 16 | var next = parent.content[nextIndex]; 17 | 18 | while (next && (next.is('space') || next.is('declarationDelimiter'))) { 19 | content += next.content; 20 | nextIndex++; 21 | next = parent.content[nextIndex]; 22 | } 23 | 24 | if (trailing.test(content) || trailingCRLF.test(content)) { 25 | result = helpers.addUnique(result, { 26 | 'ruleId': parser.rule.name, 27 | 'severity': parser.severity, 28 | 'line': space.start.line, 29 | 'column': space.start.column, 30 | 'message': 'No trailing whitespace allowed' 31 | }); 32 | } 33 | }); 34 | 35 | return result; 36 | } 37 | }; 38 | 39 | -------------------------------------------------------------------------------- /lib/rules/no-trailing-zero.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | 5 | var trailingZeroRegex = /^(\d+\.|\.)+(\d*?)0+$/; 6 | 7 | module.exports = { 8 | 'name': 'no-trailing-zero', 9 | 'defaults': { 10 | 'include': false 11 | }, 12 | 'detect': function (ast, parser) { 13 | var result = []; 14 | 15 | ast.traverseByType('number', function (num) { 16 | 17 | if (num.content.match(trailingZeroRegex)) { 18 | result = helpers.addUnique(result, { 19 | 'ruleId': parser.rule.name, 20 | 'line': num.start.line, 21 | 'column': num.start.column, 22 | 'message': 'Don\'t include trailing zeros on numbers', 23 | 'severity': parser.severity 24 | }); 25 | } 26 | }); 27 | 28 | return result; 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /lib/rules/no-universal-selectors.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | 5 | module.exports = { 6 | 'name': 'no-universal-selectors', 7 | 'defaults': {}, 8 | 'detect': function (ast, parser) { 9 | var result = []; 10 | 11 | ast.traverseByType('universalSelector', function (node) { 12 | result = helpers.addUnique(result, { 13 | 'ruleId': parser.rule.name, 14 | 'line': node.start.line, 15 | 'column': node.start.column, 16 | 'message': '* (universal) selectors are not allowed', 17 | 'severity': parser.severity 18 | }); 19 | }); 20 | 21 | return result; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /lib/rules/no-url-domains.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'), 4 | url = require('url'); 5 | 6 | module.exports = { 7 | 'name': 'no-url-domains', 8 | 'defaults': {}, 9 | 'detect': function (ast, parser) { 10 | var result = []; 11 | 12 | ast.traverseByType('uri', function (uri) { 13 | uri.traverse(function (item) { 14 | if (item.is('string')) { 15 | var stripped = helpers.stripQuotes(item.content), 16 | parsedUrl = url.parse(stripped, false, true); 17 | 18 | if (parsedUrl.host && parsedUrl.protocol !== 'data:') { 19 | result = helpers.addUnique(result, { 20 | 'ruleId': parser.rule.name, 21 | 'severity': parser.severity, 22 | 'line': item.end.line, 23 | 'column': item.end.column, 24 | 'message': 'Domains in URLs are disallowed' 25 | }); 26 | } 27 | } 28 | }); 29 | }); 30 | 31 | return result; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /lib/rules/no-warn.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | 5 | module.exports = { 6 | 'name': 'no-warn', 7 | 'defaults': {}, 8 | 'detect': function (ast, parser) { 9 | var result = []; 10 | 11 | ast.traverseByType('atkeyword', function (keyword) { 12 | keyword.traverse(function (item) { 13 | if (item.content === 'warn') { 14 | result = helpers.addUnique(result, { 15 | 'ruleId': parser.rule.name, 16 | 'line': item.start.line, 17 | 'column': item.start.column, 18 | 'message': '@warn not allowed', 19 | 'severity': parser.severity 20 | }); 21 | } 22 | }); 23 | }); 24 | 25 | return result; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /lib/rules/one-declaration-per-line.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | 5 | module.exports = { 6 | 'name': 'one-declaration-per-line', 7 | 'defaults': {}, 8 | 'detect': function (ast, parser) { 9 | var result = [], 10 | lastLine = {}; 11 | 12 | ast.traverseByType('declaration', function (declaration, i, parent) { 13 | 14 | if (declaration.start.line === lastLine.start || declaration.start.line === lastLine.end) { 15 | if (parent.type !== 'arguments') { 16 | result = helpers.addUnique(result, { 17 | 'ruleId': parser.rule.name, 18 | 'line': declaration.start.line, 19 | 'column': declaration.start.column, 20 | 'message': 'Only one declaration allowed per line', 21 | 'severity': parser.severity 22 | }); 23 | } 24 | } 25 | 26 | lastLine.start = declaration.start.line; 27 | lastLine.end = declaration.end.line; 28 | }); 29 | 30 | return result; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /lib/rules/placeholder-in-extend.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | 5 | module.exports = { 6 | 'name': 'placeholder-in-extend', 7 | 'defaults': {}, 8 | 'detect': function (ast, parser) { 9 | var result = []; 10 | 11 | ast.traverseByType('atkeyword', function (keyword, i, parent) { 12 | keyword.forEach(function (item) { 13 | if (item.content === 'extend') { 14 | 15 | parent.forEach('selector', function (selector) { 16 | var placeholder = false; 17 | 18 | selector.content.forEach(function (selectorPiece) { 19 | if (selectorPiece.type === 'placeholder') { 20 | placeholder = true; 21 | } 22 | }); 23 | 24 | if (!placeholder) { 25 | result = helpers.addUnique(result, { 26 | 'ruleId': parser.rule.name, 27 | 'line': selector.start.line, 28 | 'column': selector.start.column, 29 | 'message': '@extend must be used with a %placeholder', 30 | 'severity': parser.severity 31 | }); 32 | } 33 | }); 34 | } 35 | }); 36 | }); 37 | 38 | return result; 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /lib/rules/space-after-bang.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | 5 | module.exports = { 6 | 'name': 'space-after-bang', 7 | 'defaults': { 8 | 'include': false 9 | }, 10 | 'detect': function (ast, parser) { 11 | var result = [], 12 | regex = /!\s/; 13 | 14 | ast.traverseByTypes(['important', 'default', 'global', 'optional'], function (block) { 15 | if (block.content.match(regex) !== null) { 16 | if (parser.options.include) { 17 | result = helpers.addUnique(result, { 18 | 'ruleId': parser.rule.name, 19 | 'line': block.start.line, 20 | 'column': block.start.column + 1, 21 | 'message': 'Bangs (!) should be followed by a space', 22 | 'severity': parser.severity 23 | }); 24 | } 25 | else { 26 | result = helpers.addUnique(result, { 27 | 'ruleId': parser.rule.name, 28 | 'line': block.start.line, 29 | 'column': block.start.column, 30 | 'message': 'Bangs (!) should not be followed by a space', 31 | 'severity': parser.severity 32 | }); 33 | } 34 | } 35 | }); 36 | 37 | return result; 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /lib/rules/url-quotes.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | 5 | var isVarRegex = /^[$]/; 6 | 7 | module.exports = { 8 | 'name': 'url-quotes', 9 | 'defaults': {}, 10 | 'detect': function (ast, parser) { 11 | var result = []; 12 | 13 | ast.traverseByType('uri', function (node) { 14 | node.traverse(function (item) { 15 | if (item.is('raw')) { 16 | if (!item.content.match(isVarRegex)) { 17 | result = helpers.addUnique(result, { 18 | 'ruleId': parser.rule.name, 19 | 'severity': parser.severity, 20 | 'line': item.start.line, 21 | 'column': item.start.column, 22 | 'message': 'Quotes around URLs are required' 23 | }); 24 | } 25 | } 26 | }); 27 | }); 28 | 29 | return result; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /mocha.opts: -------------------------------------------------------------------------------- 1 | -R spec 2 | -t 4000 3 | tests tests/formatters tests/helpers tests/rules 4 | -------------------------------------------------------------------------------- /tests/bom-utf8/starts-with-mixin-utf8-bom.scss: -------------------------------------------------------------------------------- 1 | @mixin foo( 2 | $param: 'def' 3 | ) { 4 | color: red; 5 | } 6 | -------------------------------------------------------------------------------- /tests/bom-utf8/var-utf8-bom.scss: -------------------------------------------------------------------------------- 1 | $my-color: red; 2 | 3 | body { 4 | color: $my-color; 5 | } -------------------------------------------------------------------------------- /tests/cli/cli-clean.scss: -------------------------------------------------------------------------------- 1 | $red: #f00; 2 | 3 | .cli { 4 | color: $red; 5 | } 6 | -------------------------------------------------------------------------------- /tests/cli/cli-error.sass: -------------------------------------------------------------------------------- 1 | #cli 2 | color: red 3 | -------------------------------------------------------------------------------- /tests/cli/cli-error.scss: -------------------------------------------------------------------------------- 1 | #cli { 2 | color: red; 3 | } 4 | -------------------------------------------------------------------------------- /tests/cli/cli-warn.scss: -------------------------------------------------------------------------------- 1 | .cli { 2 | color: red; 3 | } 4 | -------------------------------------------------------------------------------- /tests/cli/cli.scss: -------------------------------------------------------------------------------- 1 | .cli { 2 | color: red; 3 | } 4 | -------------------------------------------------------------------------------- /tests/cli/cli.txt: -------------------------------------------------------------------------------- 1 | .cli { 2 | font-size: 100%; 3 | } 4 | -------------------------------------------------------------------------------- /tests/dir-test/dir.scss/test.scss: -------------------------------------------------------------------------------- 1 | #foo { 2 | content: ''; 3 | } 4 | -------------------------------------------------------------------------------- /tests/formatters/fixtures/broken.js: -------------------------------------------------------------------------------- 1 | var nonExistantFormatter = require('this-module-does-not-exist'); 2 | module.exports = function (results) { 3 | return nonExistantFormatter(results); 4 | }; 5 | -------------------------------------------------------------------------------- /tests/formatters/fixtures/simple.js: -------------------------------------------------------------------------------- 1 | module.exports = function (results) { 2 | var output = ''; 3 | 4 | results.forEach(function (result) { 5 | var messages = result.messages; 6 | messages.forEach(function (message) { 7 | output += 'Problem on line ' + (message.line || 0) + '\n'; 8 | }); 9 | }); 10 | 11 | return output; 12 | }; 13 | -------------------------------------------------------------------------------- /tests/helpers/getMessageType.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert'), 4 | helpers = require('../../lib/helpers'); 5 | 6 | describe('helpers - getMessageType', function () { 7 | 8 | ////////////////////////////// 9 | // Get Message Type 10 | ////////////////////////////// 11 | 12 | it('getMessageType - [severity: 1]', function (done) { 13 | var result = helpers.getMessageType({severity: 1}), 14 | expect = 'warning'; 15 | 16 | assert.equal(expect, result); 17 | done(); 18 | }); 19 | 20 | it('getMessageType - [severity: 2]', function (done) { 21 | var result = helpers.getMessageType({severity: 2}), 22 | expect = 'error'; 23 | 24 | assert.equal(expect, result); 25 | done(); 26 | }); 27 | it('getMessageType - []', function (done) { 28 | var result = helpers.getMessageType({}), 29 | expect = 'warning'; 30 | 31 | assert.equal(expect, result); 32 | done(); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /tests/helpers/hasEOL.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert'), 4 | helpers = require('../../lib/helpers'); 5 | 6 | describe('helpers - hasEOL', function () { 7 | 8 | ////////////////////////////// 9 | // hasEOL 10 | ////////////////////////////// 11 | 12 | it('hasEOL - [\'\\n\' - true]', function (done) { 13 | 14 | var result = helpers.hasEOL('\n'); 15 | 16 | assert.equal(true, result); 17 | done(); 18 | }); 19 | 20 | it('hasEOL - [\'\\r\\n\' - true]', function (done) { 21 | 22 | var result = helpers.hasEOL('\r\n'); 23 | 24 | assert.equal(true, result); 25 | done(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /tests/helpers/helpers.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert'), 4 | helpers = require('../../lib/helpers'); 5 | 6 | describe('helpers', function () { 7 | ////////////////////////////// 8 | // Helpers is loaded 9 | ////////////////////////////// 10 | 11 | it('helpers should not be undefined', function (done) { 12 | 13 | var loaded = typeof (helpers) === 'object' ? true : false; 14 | 15 | assert.equal(true, loaded); 16 | done(); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /tests/helpers/isCamelCase.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert'), 4 | helpers = require('../../lib/helpers'); 5 | 6 | describe('helpers - isCamelCase', function () { 7 | 8 | ////////////////////////////// 9 | // isCamelCase 10 | ////////////////////////////// 11 | 12 | it('isCamelCase - [\'TEST\' - false]', function (done) { 13 | 14 | var result = helpers.isCamelCase('TEST'); 15 | 16 | assert.equal(false, result); 17 | done(); 18 | }); 19 | 20 | it('isCamelCase - [\'test\' - true]', function (done) { 21 | 22 | var result = helpers.isCamelCase('test'); 23 | 24 | assert.equal(true, result); 25 | done(); 26 | }); 27 | 28 | it('isCamelCase - [abcDEF - true]', function (done) { 29 | 30 | var result = helpers.isCamelCase('abcDEF'); 31 | 32 | assert.equal(true, result); 33 | done(); 34 | }); 35 | 36 | it('isCamelCase - [\'123\' - false]', function (done) { 37 | 38 | var result = helpers.isCamelCase('123'); 39 | 40 | assert.equal(false, result); 41 | done(); 42 | }); 43 | 44 | it('isCamelCase - [\'aBcDeF\' - true]', function (done) { 45 | 46 | var result = helpers.isCamelCase('aBcDeF'); 47 | 48 | assert.equal(true, result); 49 | done(); 50 | }); 51 | }); 52 | -------------------------------------------------------------------------------- /tests/helpers/isEmptyLine.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert'), 4 | helpers = require('../../lib/helpers'); 5 | 6 | describe('helpers - isEmptyLine', function () { 7 | 8 | ////////////////////////////// 9 | // isEmptyLine 10 | ////////////////////////////// 11 | 12 | it('isEmptyLine - [\'\\n\\n\' - true]', function (done) { 13 | 14 | var result = helpers.isEmptyLine('\n\n'); 15 | 16 | assert.equal(true, result); 17 | done(); 18 | }); 19 | 20 | it('isEmptyLine - [\'\\r\\n\\r\\n\' - true]', function (done) { 21 | 22 | var result = helpers.isEmptyLine('\r\n\r\n'); 23 | 24 | assert.equal(true, result); 25 | done(); 26 | }); 27 | 28 | it('isEmptyLine - [\'\\n \\n\' - false]', function (done) { 29 | 30 | var result = helpers.isEmptyLine('\n \n'); 31 | 32 | assert.equal(false, result); 33 | done(); 34 | }); 35 | 36 | it('isEmptyLine - [\'\\r\\nabc\\r\\n\' - false]', function (done) { 37 | 38 | var result = helpers.isEmptyLine('\r\nabc\r\n'); 39 | 40 | assert.equal(false, result); 41 | done(); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /tests/helpers/isLowerCase.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert'), 4 | helpers = require('../../lib/helpers'); 5 | 6 | describe('helpers - isLowerCase', function () { 7 | 8 | ////////////////////////////// 9 | // isLowerCase 10 | ////////////////////////////// 11 | 12 | it('isLowerCase - [\'TEST\' - false]', function (done) { 13 | 14 | var result = helpers.isLowerCase('TEST'); 15 | 16 | assert.equal(false, result); 17 | done(); 18 | }); 19 | 20 | it('isLowerCase - [\'test\' - true]', function (done) { 21 | 22 | var result = helpers.isLowerCase('test'); 23 | 24 | assert.equal(true, result); 25 | done(); 26 | }); 27 | 28 | it('isLowerCase - [abcDEF - false]', function (done) { 29 | 30 | var result = helpers.isLowerCase('abcDEF'); 31 | 32 | assert.equal(false, result); 33 | done(); 34 | }); 35 | 36 | it('isLowerCase - [\'123\' - false]', function (done) { 37 | 38 | var result = helpers.isLowerCase('123'); 39 | 40 | assert.equal(false, result); 41 | done(); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /tests/helpers/isNestable.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert'), 4 | helpers = require('../../lib/helpers'); 5 | 6 | describe('helpers - isNestable', function () { 7 | 8 | ////////////////////////////// 9 | // isNestable 10 | ////////////////////////////// 11 | 12 | it('isNestable - nest attribute in selector', function (done) { 13 | var elements = ['selector', 'class', 'id', 'attribute'], 14 | nestable = ['class', 'selector', 'attribute'], 15 | previous = 'selector', 16 | current = 'attribute'; 17 | 18 | var result = helpers.isNestable(current, previous, elements, nestable); 19 | 20 | assert.equal(true, result); 21 | done(); 22 | }); 23 | 24 | it('isNestable - nest id in class', function (done) { 25 | var elements = ['selector', 'class', 'id', 'attribute'], 26 | nestable = ['class', 'selector', 'attribute'], 27 | previous = 'class', 28 | current = 'id'; 29 | 30 | var result = helpers.isNestable(current, previous, elements, nestable); 31 | 32 | assert.equal(false, result); 33 | done(); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/helpers/isNumber.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert'), 4 | helpers = require('../../lib/helpers'); 5 | 6 | describe('helpers - isNumber', function () { 7 | 8 | ////////////////////////////// 9 | // isNumber 10 | ////////////////////////////// 11 | 12 | it('isNumber - [10 - true]', function (done) { 13 | 14 | var result = helpers.isNumber(10); 15 | 16 | assert.equal(true, result); 17 | done(); 18 | }); 19 | 20 | it('isNumber - [\'10\' - true]', function (done) { 21 | 22 | var result = helpers.isNumber('10'); 23 | 24 | assert.equal(true, result); 25 | done(); 26 | }); 27 | 28 | it('isNumber - [\'ten\' - false]', function (done) { 29 | 30 | var result = helpers.isNumber('ten'); 31 | 32 | assert.equal(false, result); 33 | done(); 34 | }); 35 | 36 | it('isNumber - [\'ff00ff\' - false]', function (done) { 37 | 38 | var result = helpers.isNumber('ff00ff'); 39 | 40 | assert.equal(false, result); 41 | done(); 42 | }); 43 | 44 | }); 45 | -------------------------------------------------------------------------------- /tests/helpers/isPascalCase.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert'), 4 | helpers = require('../../lib/helpers'); 5 | 6 | describe('helpers - isPascalCase', function () { 7 | 8 | ////////////////////////////// 9 | // isPascalCase 10 | ////////////////////////////// 11 | 12 | it('isPascalCase - [\'TEST\' - true]', function (done) { 13 | 14 | var result = helpers.isPascalCase('TEST'); 15 | 16 | assert.equal(true, result); 17 | done(); 18 | }); 19 | 20 | it('isPascalCase - [\'test\' - false]', function (done) { 21 | 22 | var result = helpers.isPascalCase('test'); 23 | 24 | assert.equal(false, result); 25 | done(); 26 | }); 27 | 28 | it('isPascalCase - [AbcDEF - true]', function (done) { 29 | 30 | var result = helpers.isPascalCase('AbcDEF'); 31 | 32 | assert.equal(true, result); 33 | done(); 34 | }); 35 | 36 | it('isPascalCase - [\'123\' - false]', function (done) { 37 | 38 | var result = helpers.isPascalCase('123'); 39 | 40 | assert.equal(false, result); 41 | done(); 42 | }); 43 | 44 | it('isPascalCase - [\'ABcDeF\' - true]', function (done) { 45 | 46 | var result = helpers.isPascalCase('ABcDeF'); 47 | 48 | assert.equal(true, result); 49 | done(); 50 | }); 51 | }); 52 | -------------------------------------------------------------------------------- /tests/helpers/isUpperCase.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert'), 4 | helpers = require('../../lib/helpers'); 5 | 6 | describe('helpers - isUpperCase', function () { 7 | 8 | ////////////////////////////// 9 | // isUpperCase 10 | ////////////////////////////// 11 | 12 | it('isUpperCase - [\'TEST\' - true]', function (done) { 13 | 14 | var result = helpers.isUpperCase('TEST'); 15 | 16 | assert.equal(true, result); 17 | done(); 18 | }); 19 | 20 | it('isUpperCase - [\'test\' - false]', function (done) { 21 | 22 | var result = helpers.isUpperCase('test'); 23 | 24 | assert.equal(false, result); 25 | done(); 26 | }); 27 | 28 | it('isUpperCase - [abcDEF - false]', function (done) { 29 | 30 | var result = helpers.isUpperCase('abcDEF'); 31 | 32 | assert.equal(false, result); 33 | done(); 34 | }); 35 | 36 | it('isUpperCase - [\'123\' - false]', function (done) { 37 | 38 | var result = helpers.isUpperCase('123'); 39 | 40 | assert.equal(false, result); 41 | done(); 42 | }); 43 | 44 | }); 45 | -------------------------------------------------------------------------------- /tests/helpers/loadConfigFile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert'), 4 | helpers = require('../../lib/helpers'); 5 | 6 | describe('helpers - loadConfigFile', function () { 7 | 8 | ////////////////////////////// 9 | // loadConfigFile 10 | ////////////////////////////// 11 | 12 | it('loadConfigFile', function (done) { 13 | 14 | var result = helpers.loadConfigFile('../../tests/testFile.txt'), 15 | expect = 'This is a test file that test\'s the loadConfigFile helper function.'; 16 | 17 | assert.equal(expect, result); 18 | done(); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /tests/helpers/propertySearch.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert'), 4 | helpers = require('../../lib/helpers'); 5 | 6 | var haystack = [ 7 | { 8 | prop: 'a', 9 | propb: 'b' 10 | }, 11 | { 12 | prop: 'c', 13 | propb: 'd' 14 | } 15 | ]; 16 | 17 | describe('helpers - propertySearch', function () { 18 | ////////////////////////////// 19 | // propertySearch 20 | ////////////////////////////// 21 | 22 | it('propertySearch should not find a property', function (done) { 23 | 24 | var needle = 'e', 25 | property = 'prop', 26 | result = helpers.propertySearch(haystack, needle, property); 27 | 28 | assert.equal(-1, result); 29 | done(); 30 | }); 31 | 32 | it('propertySearch should find a property', function (done) { 33 | 34 | var needle = 'a', 35 | property = 'prop', 36 | result = helpers.propertySearch(haystack, needle, property); 37 | 38 | assert.equal(0, result); 39 | done(); 40 | }); 41 | 42 | it('propertySearch should find a deeper property', function (done) { 43 | 44 | var needle = 'd', 45 | property = 'propb', 46 | result = helpers.propertySearch(haystack, needle, property); 47 | 48 | assert.equal(1, result); 49 | done(); 50 | }); 51 | }); 52 | -------------------------------------------------------------------------------- /tests/helpers/stripBom.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert'), 4 | helpers = require('../../lib/helpers'), 5 | fs = require('fs'); 6 | 7 | describe('helpers - stripBom', function () { 8 | 9 | ////////////////////////////// 10 | // Strip BOM 11 | ////////////////////////////// 12 | 13 | it('should remove the BOM marker', function (done) { 14 | var file = fs.readFileSync('tests/bom-utf8/starts-with-mixin-utf8-bom.scss').toString(); 15 | assert.equal(file.charCodeAt(0), 0xFEFF); 16 | assert.notEqual(helpers.stripBom(file).charCodeAt(0), 0xFEFF); 17 | done(); 18 | }); 19 | 20 | it('should throw an error if not passed a string', function (done) { 21 | assert.throws( 22 | function () { 23 | helpers.stripBom(8); 24 | }, Error 25 | ); 26 | done(); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /tests/helpers/stripLastSpace.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert'), 4 | helpers = require('../../lib/helpers'); 5 | 6 | describe('helpers - stripLastSpace', function () { 7 | 8 | ////////////////////////////// 9 | // stripLastSpace 10 | ////////////////////////////// 11 | 12 | it('stripLastSpace - [\'selector \']', function (done) { 13 | 14 | var result = helpers.stripLastSpace('selector '); 15 | 16 | assert.equal('selector', result); 17 | done(); 18 | }); 19 | 20 | it('stripLastSpace - [\'selector test \']', function (done) { 21 | 22 | var result = helpers.stripLastSpace('selector test'); 23 | 24 | assert.equal('selector test', result); 25 | done(); 26 | }); 27 | 28 | it('stripLastSpace - [\'selector\']', function (done) { 29 | 30 | var result = helpers.stripLastSpace('selector'); 31 | 32 | assert.equal('selector', result); 33 | done(); 34 | }); 35 | 36 | it('stripLastSpace - [\'selector test\']', function (done) { 37 | 38 | var result = helpers.stripLastSpace('selector test'); 39 | 40 | assert.equal('selector test', result); 41 | done(); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /tests/helpers/stripQuotes.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert'), 4 | helpers = require('../../lib/helpers'); 5 | 6 | describe('helpers - stripQuotes', function () { 7 | 8 | ////////////////////////////// 9 | // Strip quotes 10 | ////////////////////////////// 11 | 12 | it('stripQuotes - [double quotes]', function (done) { 13 | var result = helpers.stripQuotes('"This is a string"'), 14 | expect = 'This is a string'; 15 | 16 | assert.equal(expect, result); 17 | done(); 18 | }); 19 | 20 | it('stripQuotes - [single quotes]', function (done) { 21 | var result = helpers.stripQuotes('\'This is a string\''), 22 | expect = 'This is a string'; 23 | 24 | assert.equal(expect, result); 25 | done(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /tests/rules/_lint.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('../../index'), 4 | assert = require('assert'), 5 | fs = require('fs'), 6 | path = require('path'); 7 | 8 | module.exports.file = function (file) { 9 | var result = {}; 10 | file = path.join(process.cwd(), 'tests', 'sass', file); 11 | 12 | result = { 13 | 'text': fs.readFileSync(file), 14 | 'format': path.extname(file).replace('.', ''), 15 | 'filename': path.basename(file) 16 | }; 17 | 18 | return result; 19 | }; 20 | 21 | module.exports.test = function (text, options, cb) { 22 | var results; 23 | 24 | options = { 25 | 'options': { 26 | 'merge-default-rules': false, 27 | 'cache-config': false 28 | }, 29 | 'rules': options 30 | }; 31 | 32 | results = lint.lintText(text, options); 33 | 34 | cb(results); 35 | }; 36 | 37 | module.exports.assert = assert; 38 | -------------------------------------------------------------------------------- /tests/rules/declarations-before-nesting.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('declarations before nesting - scss', function () { 9 | var file = lint.file('declarations-before-nesting.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'declarations-before-nesting': 1 14 | }, function (data) { 15 | lint.assert.equal(4, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('declarations before nesting - sass', function () { 25 | var file = lint.file('declarations-before-nesting.sass'); 26 | 27 | it('enforce', function (done) { 28 | lint.test(file, { 29 | 'declarations-before-nesting': 1 30 | }, function (data) { 31 | lint.assert.equal(4, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/extends-before-declarations.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('extends before declarations - scss', function () { 9 | var file = lint.file('extends-before-declarations.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'extends-before-declarations': 1 14 | }, function (data) { 15 | lint.assert.equal(4, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('extends before declarations - sass', function () { 25 | var file = lint.file('extends-before-declarations.sass'); 26 | 27 | it('enforce', function (done) { 28 | lint.test(file, { 29 | 'extends-before-declarations': 1 30 | }, function (data) { 31 | lint.assert.equal(4, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/extends-before-mixins.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('extends before mixins - scss', function () { 9 | var file = lint.file('extends-before-mixins.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'extends-before-mixins': 1 14 | }, function (data) { 15 | lint.assert.equal(2, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('extends before mixins - sass', function () { 25 | var file = lint.file('extends-before-mixins.sass'); 26 | 27 | it('enforce', function (done) { 28 | lint.test(file, { 29 | 'extends-before-mixins': 1 30 | }, function (data) { 31 | lint.assert.equal(2, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/force-attribute-nesting.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('force attribute nesting - scss', function () { 9 | var file = lint.file('force-attribute-nesting.scss'); 10 | 11 | it('[default]', function (done) { 12 | lint.test(file, { 13 | 'force-attribute-nesting': 1 14 | }, function (data) { 15 | lint.assert.equal(5, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('force attribute nesting - sass', function () { 25 | var file = lint.file('force-attribute-nesting.sass'); 26 | 27 | it('[default]', function (done) { 28 | lint.test(file, { 29 | 'force-attribute-nesting': 1 30 | }, function (data) { 31 | lint.assert.equal(5, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/force-element-nesting.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('force element nesting - scss', function () { 9 | var file = lint.file('force-element-nesting.scss'); 10 | 11 | it('[default]', function (done) { 12 | lint.test(file, { 13 | 'force-element-nesting': 1 14 | }, function (data) { 15 | lint.assert.equal(10, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('force element nesting - sass', function () { 25 | var file = lint.file('force-element-nesting.sass'); 26 | 27 | it('[default]', function (done) { 28 | lint.test(file, { 29 | 'force-element-nesting': 1 30 | }, function (data) { 31 | lint.assert.equal(10, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/force-pseudo-nesting.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('force pseudo nesting - scss', function () { 9 | var file = lint.file('force-pseudo-nesting.scss'); 10 | 11 | it('[default]', function (done) { 12 | lint.test(file, { 13 | 'force-pseudo-nesting': 1 14 | }, function (data) { 15 | lint.assert.equal(6, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('force pseudo nesting - sass', function () { 25 | var file = lint.file('force-pseudo-nesting.sass'); 26 | 27 | it('[default]', function (done) { 28 | lint.test(file, { 29 | 'force-pseudo-nesting': 1 30 | }, function (data) { 31 | lint.assert.equal(6, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/no-attribute-selectors.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('no attribute selectors - scss', function () { 9 | var file = lint.file('no-attribute-selectors.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'no-attribute-selectors': 1 14 | }, function (data) { 15 | lint.assert.equal(21, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('no attribute selectors - sass', function () { 25 | var file = lint.file('no-attribute-selectors.sass'); 26 | 27 | it('enforce', function (done) { 28 | lint.test(file, { 29 | 'no-attribute-selectors': 1 30 | }, function (data) { 31 | lint.assert.equal(21, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/no-color-hex.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('no color hex - scss', function () { 9 | var file = lint.file('no-color-hex.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'no-color-hex': 1 14 | }, function (data) { 15 | lint.assert.equal(9, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('no color hex - sass', function () { 25 | var file = lint.file('no-color-hex.sass'); 26 | 27 | it('enforce', function (done) { 28 | lint.test(file, { 29 | 'no-color-hex': 1 30 | }, function (data) { 31 | lint.assert.equal(9, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/no-color-keywords.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('no color keywords - scss', function () { 9 | var file = lint.file('no-color-keywords.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'no-color-keywords': 1 14 | }, function (data) { 15 | lint.assert.equal(8, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('no color keywords - sass', function () { 25 | var file = lint.file('no-color-keywords.sass'); 26 | 27 | it('enforce', function (done) { 28 | lint.test(file, { 29 | 'no-color-keywords': 1 30 | }, function (data) { 31 | lint.assert.equal(8, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/no-combinators.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('no combinators - scss', function () { 9 | var file = lint.file('no-combinators.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'no-combinators': 1 14 | }, function (data) { 15 | lint.assert.equal(23, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('no combinators - sass', function () { 25 | var file = lint.file('no-combinators.sass'); 26 | 27 | it('enforce', function (done) { 28 | lint.test(file, { 29 | 'no-combinators': 1 30 | }, function (data) { 31 | lint.assert.equal(23, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/no-css-comments.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('no css comments - scss', function () { 9 | var file = lint.file('no-css-comments.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'no-css-comments': 1 14 | }, function (data) { 15 | lint.assert.equal(4, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('no css comments - sass', function () { 25 | var file = lint.file('no-css-comments.sass'); 26 | 27 | it('enforce', function (done) { 28 | lint.test(file, { 29 | 'no-css-comments': 1 30 | }, function (data) { 31 | lint.assert.equal(4, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/no-debug.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('no debug - scss', function () { 9 | var file = lint.file('no-debug.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'no-debug': 1 14 | }, function (data) { 15 | lint.assert.equal(3, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('no debug - sass', function () { 25 | var file = lint.file('no-debug.sass'); 26 | 27 | it('enforce', function (done) { 28 | lint.test(file, { 29 | 'no-debug': 1 30 | }, function (data) { 31 | lint.assert.equal(3, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/no-empty-rulesets.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('no empty rulesets - scss', function () { 9 | var file = lint.file('no-empty-rulesets.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'no-empty-rulesets': 1 14 | }, function (data) { 15 | lint.assert.equal(4, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /tests/rules/no-extends.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('no extends - scss', function () { 9 | var file = lint.file('no-extends.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'no-extends': 1 14 | }, function (data) { 15 | lint.assert.equal(1, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('no extends - sass', function () { 25 | var file = lint.file('no-extends.sass'); 26 | 27 | it('enforce', function (done) { 28 | lint.test(file, { 29 | 'no-extends': 1 30 | }, function (data) { 31 | lint.assert.equal(1, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/no-ids.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('no ids - scss', function () { 9 | var file = lint.file('no-ids.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'no-ids': 1 14 | }, function (data) { 15 | lint.assert.equal(2, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('no ids - sass', function () { 25 | var file = lint.file('no-ids.sass'); 26 | 27 | it('enforce', function (done) { 28 | lint.test(file, { 29 | 'no-ids': 1 30 | }, function (data) { 31 | lint.assert.equal(2, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/no-important.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('no important - scss', function () { 9 | var file = lint.file('no-important.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'no-important': 1 14 | }, function (data) { 15 | lint.assert.equal(1, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('no important - sass', function () { 25 | var file = lint.file('no-important.sass'); 26 | 27 | it('enforce', function (done) { 28 | lint.test(file, { 29 | 'no-important': 1 30 | }, function (data) { 31 | lint.assert.equal(1, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/no-invalid-hex.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('no invalid hex - scss', function () { 9 | var file = lint.file('no-invalid-hex.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'no-invalid-hex': 1 14 | }, function (data) { 15 | lint.assert.equal(16, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('no invalid hex - sass', function () { 25 | var file = lint.file('no-invalid-hex.sass'); 26 | 27 | it('enforce', function (done) { 28 | lint.test(file, { 29 | 'no-invalid-hex': 1 30 | }, function (data) { 31 | lint.assert.equal(16, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/no-trailing-whitespace.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('no trailing whitespace - scss', function () { 9 | var file = lint.file('no-trailing-whitespace.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'no-trailing-whitespace': 1 14 | }, function (data) { 15 | lint.assert.equal(5, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('no trailing whitespace - sass', function () { 25 | var file = lint.file('no-trailing-whitespace.sass'); 26 | 27 | it('enforce', function (done) { 28 | lint.test(file, { 29 | 'no-trailing-whitespace': 1 30 | }, function (data) { 31 | lint.assert.equal(5, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/no-trailing-zero.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('no trailing zero - scss', function () { 9 | var file = lint.file('no-trailing-zero.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'no-trailing-zero': 1 14 | }, function (data) { 15 | lint.assert.equal(8, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('no trailing zero - sass', function () { 25 | var file = lint.file('no-trailing-zero.sass'); 26 | 27 | it('enforce', function (done) { 28 | lint.test(file, { 29 | 'no-trailing-zero': 1 30 | }, function (data) { 31 | lint.assert.equal(8, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/no-transition-all.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('no transition all - scss', function () { 9 | var file = lint.file('no-transition-all.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'no-transition-all': 1 14 | }, function (data) { 15 | lint.assert.equal(5, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('no transition all - sass', function () { 25 | var file = lint.file('no-transition-all.sass'); 26 | 27 | it('enforce', function (done) { 28 | lint.test(file, { 29 | 'no-transition-all': 1 30 | }, function (data) { 31 | lint.assert.equal(5, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/no-universal-selectors.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('no universal selectors - scss', function () { 9 | var file = lint.file('no-universal-selectors.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'no-universal-selectors': 1 14 | }, function (data) { 15 | lint.assert.equal(6, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('no universal selectors - sass', function () { 25 | var file = lint.file('no-universal-selectors.sass'); 26 | 27 | it('enforce', function (done) { 28 | lint.test(file, { 29 | 'no-universal-selectors': 1 30 | }, function (data) { 31 | lint.assert.equal(6, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/no-url-domains.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('no url domains - scss', function () { 9 | var file = lint.file('no-url-domains.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'no-url-domains': 1 14 | }, function (data) { 15 | lint.assert.equal(3, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('no url domains - sass', function () { 25 | var file = lint.file('no-url-domains.sass'); 26 | 27 | it('enforce', function (done) { 28 | lint.test(file, { 29 | 'no-url-domains': 1 30 | }, function (data) { 31 | lint.assert.equal(3, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/no-warn.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('no warn - scss', function () { 9 | var file = lint.file('no-warn.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'no-warn': 1 14 | }, function (data) { 15 | lint.assert.equal(3, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('no warn - sass', function () { 25 | var file = lint.file('no-warn.sass'); 26 | 27 | it('enforce', function (done) { 28 | lint.test(file, { 29 | 'no-warn': 1 30 | }, function (data) { 31 | lint.assert.equal(3, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/one-declaration-per-line.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('one declaration per line - scss', function () { 9 | var file = lint.file('one-declaration-per-line.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'one-declaration-per-line': 1 14 | }, function (data) { 15 | lint.assert.equal(2, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /tests/rules/placeholder-in-extend.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('placeholder in extend - scss', function () { 9 | var file = lint.file('placeholder-in-extend.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'placeholder-in-extend': 1 14 | }, function (data) { 15 | lint.assert.equal(1, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('placeholder in extend - sass', function () { 25 | var file = lint.file('placeholder-in-extend.sass'); 26 | 27 | it('enforce', function (done) { 28 | lint.test(file, { 29 | 'placeholder-in-extend': 1 30 | }, function (data) { 31 | lint.assert.equal(1, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/single-line-per-selector.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('single line per selector - scss', function () { 9 | var file = lint.file('single-line-per-selector.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'single-line-per-selector': 1 14 | }, function (data) { 15 | lint.assert.equal(6, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('single line per selector - sass', function () { 25 | var file = lint.file('single-line-per-selector.sass'); 26 | 27 | it('enforce', function (done) { 28 | lint.test(file, { 29 | 'single-line-per-selector': 1 30 | }, function (data) { 31 | lint.assert.equal(6, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/rules/space-before-brace.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('space before brace - scss', function () { 9 | var file = lint.file('space-before-brace.scss'); 10 | 11 | it('[include: true]', function (done) { 12 | lint.test(file, { 13 | 'space-before-brace': 1 14 | }, function (data) { 15 | lint.assert.equal(5, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | 20 | it('[include: false]', function (done) { 21 | lint.test(file, { 22 | 'space-before-brace': [ 23 | 1, 24 | { 25 | 'include': false 26 | } 27 | ] 28 | }, function (data) { 29 | lint.assert.equal(11, data.warningCount); 30 | done(); 31 | }); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /tests/rules/trailing-semicolon.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('trailing semicolon - scss', function () { 9 | var file = lint.file('trailing-semicolon.scss'); 10 | 11 | it('[include: true]', function (done) { 12 | lint.test(file, { 13 | 'trailing-semicolon': 1 14 | }, function (data) { 15 | lint.assert.equal(9, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | 20 | it('[include: false]', function (done) { 21 | lint.test(file, { 22 | 'trailing-semicolon': [ 23 | 1, 24 | { 25 | 'include': false 26 | } 27 | ] 28 | }, function (data) { 29 | lint.assert.equal(5, data.warningCount); 30 | done(); 31 | }); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /tests/rules/url-quotes.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var lint = require('./_lint'); 4 | 5 | ////////////////////////////// 6 | // SCSS syntax tests 7 | ////////////////////////////// 8 | describe('url quotes - scss', function () { 9 | var file = lint.file('url-quotes.scss'); 10 | 11 | it('enforce', function (done) { 12 | lint.test(file, { 13 | 'url-quotes': 1 14 | }, function (data) { 15 | lint.assert.equal(1, data.warningCount); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | ////////////////////////////// 22 | // Sass syntax tests 23 | ////////////////////////////// 24 | describe('url quotes - sass', function () { 25 | var file = lint.file('url-quotes.sass'); 26 | 27 | it('enforce', function (done) { 28 | lint.test(file, { 29 | 'url-quotes': 1 30 | }, function (data) { 31 | lint.assert.equal(1, data.warningCount); 32 | done(); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /tests/sass/attribute-quotes.sass: -------------------------------------------------------------------------------- 1 | span[lang] 2 | font-weight: bold 3 | 4 | //////////////////////////// 5 | // No Quotes - Default warnings 6 | //////////////////////////// 7 | 8 | span[lang=pt] 9 | color: green 10 | 11 | span[lang~=en-us] 12 | color: blue 13 | 14 | span[lang|=zh] 15 | color: red 16 | 17 | span[class^=main] 18 | background-color: yellow 19 | 20 | // Invalid CSS - must be ident or string 21 | // a[href^=#] { 22 | // background-color: gold; 23 | // } 24 | // 25 | // a[href$=.cn] { 26 | // color: red; 27 | // } 28 | 29 | a[href*=example] 30 | background-color: #CCCCCC 31 | 32 | input[type=email i] 33 | border-color: blue 34 | 35 | //////////////////////////// 36 | // Quotes - exclude option warnings 37 | //////////////////////////// 38 | 39 | span[lang="pt"] 40 | color: green 41 | 42 | span[lang~="en-us"] 43 | color: blue 44 | 45 | span[lang|="zh"] 46 | color: red 47 | 48 | span[class^="main"] 49 | background-color: yellow 50 | 51 | a[href^="#"] 52 | background-color: gold 53 | 54 | a[href$=".cn"] 55 | color: red 56 | 57 | a[href*="example"] 58 | background-color: #CCCCCC 59 | 60 | input[type="email" i] 61 | border-color: blue 62 | -------------------------------------------------------------------------------- /tests/sass/bem-depth.sass: -------------------------------------------------------------------------------- 1 | .one 2 | color: red 3 | &__two 4 | color: blue 5 | &__three 6 | color: green 7 | &__two-again 8 | color: pink 9 | 10 | .one__two 11 | color: red 12 | &--modifier 13 | color: blue 14 | &__three 15 | color: green 16 | &--modifier__three 17 | color: white 18 | 19 | .block 20 | color: red 21 | 22 | .block__element-one 23 | color: red 24 | 25 | .block__element-one__element-two 26 | color: red 27 | 28 | %one__two 29 | color: red 30 | 31 | %one__two__three 32 | color: blue 33 | 34 | %one__two__three__four 35 | color: blue 36 | -------------------------------------------------------------------------------- /tests/sass/bem-depth.scss: -------------------------------------------------------------------------------- 1 | .one { 2 | color: red; 3 | 4 | &__two { 5 | color: blue; 6 | 7 | &__three { 8 | color: green; 9 | } 10 | } 11 | 12 | &__two-again { 13 | color: pink; 14 | } 15 | } 16 | 17 | .one__two { 18 | color: red; 19 | 20 | &--modifier { 21 | color: blue; 22 | } 23 | 24 | &__three { 25 | color: green; 26 | } 27 | 28 | &--modifier__three { 29 | color: white; 30 | } 31 | } 32 | 33 | .block { 34 | color: red; 35 | } 36 | 37 | .block__element-one { 38 | color: red; 39 | } 40 | 41 | .block__element-one__element-two { 42 | color: red; 43 | } 44 | 45 | %one__two { 46 | color: red; 47 | } 48 | 49 | %one__two__three { 50 | color: blue; 51 | } 52 | 53 | %one__two__three__four { 54 | color: blue; 55 | } 56 | -------------------------------------------------------------------------------- /tests/sass/border-zero.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | border: 0 3 | 4 | 5 | .bar 6 | border: none 7 | 8 | 9 | .baz 10 | border-right: 0 11 | 12 | 13 | .qux 14 | border-left: none 15 | 16 | 17 | .fail 18 | border-top: none 19 | 20 | 21 | .norf 22 | border: 1px 23 | -------------------------------------------------------------------------------- /tests/sass/border-zero.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | border: 0; 3 | } 4 | 5 | .bar { 6 | border: none; 7 | } 8 | 9 | .baz { 10 | border-right: 0; 11 | } 12 | 13 | .qux { 14 | border-left: none; 15 | } 16 | 17 | .fail { 18 | border-top: none; 19 | } 20 | 21 | .norf { 22 | border: 1px; 23 | } 24 | 25 | .norf { 26 | // sass-lint:disable border-zero 27 | border: none; 28 | // sass-lint:enable border-zero 29 | } 30 | -------------------------------------------------------------------------------- /tests/sass/clean-import-paths.sass: -------------------------------------------------------------------------------- 1 | // Clean paths 2 | @import foo 3 | @import bar/foo 4 | 5 | // Only filename extensions 6 | @import foo.scss 7 | @import bar/foo.scss 8 | 9 | // Only leading underscores 10 | @import _foo 11 | @import bar/_foo 12 | 13 | // Both leading underscores and filename extensions 14 | @import _foo.scss 15 | @import bar/_foo.scss 16 | 17 | // CSS imports - ignore 18 | @import url(fineprint.css) 19 | @import url(bluish.css) projection, tv 20 | @import custom.css 21 | @import url(chrome://communicator/skin/) 22 | @import common.css screen, projection 23 | @import url(landscape.css) screen and (orientation: landscape) 24 | 25 | @if variable-exists(google-fonts-url) 26 | @import url($google-fonts-url) 27 | -------------------------------------------------------------------------------- /tests/sass/clean-import-paths.scss: -------------------------------------------------------------------------------- 1 | // Clean paths 2 | @import 'foo'; 3 | @import 'bar/foo'; 4 | 5 | // Only filename extensions 6 | @import 'foo.scss'; 7 | @import 'bar/foo.scss'; 8 | 9 | // Only leading underscores 10 | @import '_foo'; 11 | @import 'bar/_foo'; 12 | 13 | // Both leading underscores and filename extensions 14 | @import '_foo.scss'; 15 | @import 'bar/_foo.scss'; 16 | 17 | // CSS imports - ignore 18 | @import url('fineprint.css'); 19 | @import url('bluish.css') projection, tv; 20 | @import 'custom.css'; 21 | @import url('chrome://communicator/skin/'); 22 | @import 'common.css' screen, projection; 23 | @import url('landscape.css') screen and (orientation: landscape); 24 | 25 | @if variable-exists(google-fonts-url) { 26 | @import url($google-fonts-url); 27 | } 28 | 29 | // Test dot in filename 30 | @import '../../node_modules/inuit-normalize/generic.normalize'; 31 | -------------------------------------------------------------------------------- /tests/sass/declarations-before-nesting.sass: -------------------------------------------------------------------------------- 1 | .bar 2 | content: 'baz' 3 | 4 | .qux 5 | content: 'baz' 6 | 7 | .foo 8 | .bar 9 | content: 'where' 10 | 11 | content: 'baz' 12 | 13 | .baz 14 | content: 'where' 15 | 16 | content: 'baz' 17 | 18 | .foo 19 | .bar 20 | content: 'where' 21 | 22 | .baz 23 | content: 'quz' 24 | 25 | content: 'baz' 26 | 27 | content: 'baz' 28 | 29 | // issue #935 - ignore variables 30 | +foo 31 | #{$bar} 32 | content: 'foobar' 33 | 34 | $baz: 'qux' 35 | -------------------------------------------------------------------------------- /tests/sass/declarations-before-nesting.scss: -------------------------------------------------------------------------------- 1 | .bar { 2 | content: 'baz'; 3 | 4 | .qux { 5 | content: 'baz'; 6 | } 7 | } 8 | 9 | .foo { 10 | .bar { 11 | content: 'where'; 12 | } 13 | 14 | content: 'baz'; 15 | 16 | .baz { 17 | content: 'where'; 18 | } 19 | 20 | content: 'baz'; 21 | } 22 | 23 | .foo { 24 | .bar { 25 | content: 'where'; 26 | 27 | .baz { 28 | content: 'quz'; 29 | } 30 | 31 | content: 'baz'; 32 | } 33 | 34 | content: 'baz'; 35 | } 36 | 37 | // issue #935 - ignore variables 38 | @mixin foo { 39 | #{$bar} { 40 | content: 'foobar'; 41 | } 42 | 43 | $baz: 'qux'; 44 | } 45 | -------------------------------------------------------------------------------- /tests/sass/empty-args.sass: -------------------------------------------------------------------------------- 1 | // No arguments with parenthesis 2 | =foo() 3 | color: red 4 | 5 | 6 | .foo 7 | +foo() 8 | 9 | 10 | 11 | 12 | // No arguments with no parenthesis 13 | =bar 14 | color: orange 15 | 16 | 17 | .bar 18 | +bar 19 | 20 | 21 | 22 | 23 | // Arguments with parenthesis 24 | =baz($color) 25 | color: $color 26 | 27 | 28 | $foo: blue 29 | 30 | .baz 31 | +baz($foo) 32 | 33 | 34 | 35 | 36 | // Parenthesis only where required 37 | =qux($color: lime) 38 | color: $color 39 | 40 | 41 | .qux 42 | +qux 43 | -------------------------------------------------------------------------------- /tests/sass/empty-args.scss: -------------------------------------------------------------------------------- 1 | // No arguments with parenthesis 2 | @mixin foo() { 3 | color: red; 4 | } 5 | 6 | .foo { 7 | @include foo(); 8 | } 9 | 10 | 11 | 12 | // No arguments with no parenthesis 13 | @mixin bar { 14 | color: orange; 15 | } 16 | 17 | .bar { 18 | @include bar; 19 | } 20 | 21 | 22 | 23 | // Arguments with parenthesis 24 | @mixin baz($color) { 25 | color: $color; 26 | } 27 | 28 | $foo: blue; 29 | 30 | .baz { 31 | @include baz($foo); 32 | } 33 | 34 | 35 | 36 | // Parenthesis only where required 37 | @mixin qux($color: lime) { 38 | color: $color; 39 | } 40 | 41 | .qux { 42 | @include qux; 43 | } 44 | -------------------------------------------------------------------------------- /tests/sass/empty-file.sass: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sasstools/sass-lint/52ccf2e1fa3e4d17d9f8f7bd748f7caf20830f30/tests/sass/empty-file.sass -------------------------------------------------------------------------------- /tests/sass/empty-file.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sasstools/sass-lint/52ccf2e1fa3e4d17d9f8f7bd748f7caf20830f30/tests/sass/empty-file.scss -------------------------------------------------------------------------------- /tests/sass/empty-line-between-blocks.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | content: 'foo' 3 | 4 | .foo 5 | content: 'foo' 6 | .bar 7 | content: 'bar' 8 | 9 | .foo 10 | @include bar 11 | 12 | .foo 13 | @include bar($qux) 14 | content: 'foo' 15 | 16 | 17 | .foo 18 | @include bar($qux) 19 | content: 'foo' 20 | 21 | 22 | .foo 23 | 24 | @include bar($qux) 25 | content: 'foo' 26 | 27 | 28 | .foo 29 | @include bar($qux) 30 | &:after 31 | content: 'foo' 32 | 33 | 34 | 35 | .foo 36 | 37 | &__bar 38 | content: 'foo' 39 | 40 | 41 | content: 'foo' 42 | 43 | .foo 44 | content: 'foo' 45 | 46 | &__bar 47 | content: 'foo' 48 | 49 | 50 | .foo 51 | content: 'foo' 52 | 53 | &__bar 54 | content: 'foo' 55 | 56 | 57 | 58 | .foo 59 | &:before 60 | content: 'foo' 61 | 62 | 63 | .foo 64 | content: 'foo' 65 | 66 | &::first-line 67 | content: 'foo' 68 | 69 | 70 | h1 71 | content: 'foo' 72 | h2 73 | content: 'foo' 74 | h3 75 | content: 'foo' 76 | h4 77 | content: 'foo' 78 | 79 | 80 | .foo + .bar 81 | content: 'foo' 82 | .foo + .bar, 83 | h2 84 | content: 'foo' 85 | 86 | 87 | [type=text] 88 | content: 'foo' 89 | h1.foo 90 | content: 'foo' 91 | -------------------------------------------------------------------------------- /tests/sass/extends-before-declarations.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | @extend %waldo 3 | content: 'baz' 4 | 5 | 6 | .bar 7 | content: 'baz' 8 | @extend %waldo 9 | 10 | 11 | .qux 12 | content: 'baz' 13 | @extend %waldo 14 | content: 'where' 15 | 16 | 17 | .breakpoint 18 | content: 'baz' 19 | @extend %foo 20 | 21 | .foo 22 | content: 'where' 23 | 24 | @extend %waldo 25 | 26 | 27 | .bar 28 | @extend %waldo 29 | content: 'where' 30 | 31 | 32 | .foo-noextend 33 | +foo 34 | content: "bar" 35 | -------------------------------------------------------------------------------- /tests/sass/extends-before-declarations.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | @extend %waldo; 3 | content: 'baz'; 4 | } 5 | 6 | .bar { 7 | content: 'baz'; 8 | @extend %waldo; 9 | } 10 | 11 | .qux { 12 | content: 'baz'; 13 | @extend %waldo; 14 | content: 'where'; 15 | } 16 | 17 | .breakpoint { 18 | content: 'baz'; 19 | @extend %foo; 20 | 21 | .foo { 22 | content: 'where'; 23 | 24 | @extend %waldo; 25 | } 26 | 27 | .bar { 28 | @extend %waldo; 29 | content: 'where'; 30 | } 31 | } 32 | 33 | .foo-noextend { 34 | @include foo; 35 | } 36 | -------------------------------------------------------------------------------- /tests/sass/extends-before-mixins.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | @extend %waldo 3 | +foo 4 | 5 | 6 | .bar 7 | +foo 8 | @extend %waldo 9 | 10 | 11 | .baz 12 | @extend %waldo 13 | +foo 14 | @extend %qux 15 | -------------------------------------------------------------------------------- /tests/sass/extends-before-mixins.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | @extend %waldo; 3 | @include foo; 4 | } 5 | 6 | .bar { 7 | @include foo; 8 | @extend %waldo; 9 | } 10 | 11 | .baz { 12 | @extend %waldo; 13 | @include foo; 14 | @extend %qux; 15 | } 16 | -------------------------------------------------------------------------------- /tests/sass/final-newline--import.sass: -------------------------------------------------------------------------------- 1 | @import 'foo' 2 | -------------------------------------------------------------------------------- /tests/sass/final-newline--import.scss: -------------------------------------------------------------------------------- 1 | @import 'foo'; 2 | -------------------------------------------------------------------------------- /tests/sass/final-newline--nested.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | @if $foo == 'bar' 3 | content: 'bar' 4 | -------------------------------------------------------------------------------- /tests/sass/final-newline--nested.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | @if $foo == 'bar' { 3 | content: 'bar'; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /tests/sass/final-newline--none.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | content: bar -------------------------------------------------------------------------------- /tests/sass/final-newline--none.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | content: bar; 3 | } -------------------------------------------------------------------------------- /tests/sass/final-newline--return.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | content: bar 3 | -------------------------------------------------------------------------------- /tests/sass/final-newline--return.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | content: bar; 3 | } 4 | -------------------------------------------------------------------------------- /tests/sass/final-newline--space.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | content: bar -------------------------------------------------------------------------------- /tests/sass/final-newline--space.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | content: bar; 3 | } -------------------------------------------------------------------------------- /tests/sass/force-attribute-nesting.sass: -------------------------------------------------------------------------------- 1 | // attribute should be nested 2 | input[type='text'] 3 | border: 0 4 | 5 | // attribute should be nested 6 | input[type='radio'] 7 | color: red 8 | 9 | // attribute should be nested 10 | a[target='_blank'] 11 | content: '' 12 | 13 | input 14 | &[type='text'] 15 | content: '' 16 | 17 | form 18 | // attribute should be nested 19 | input[type='text'] 20 | padding: 0 21 | 22 | .form 23 | // attribute should be nested 24 | .class input[type='text'] 25 | padding: 0 26 | -------------------------------------------------------------------------------- /tests/sass/force-attribute-nesting.scss: -------------------------------------------------------------------------------- 1 | // attribute should be nested 2 | input[type='text'] { 3 | border: 0; 4 | } 5 | 6 | // attribute should be nested 7 | input[type='radio'] { 8 | color: red; 9 | } 10 | 11 | // attribute should be nested 12 | a[target='_blank'] { 13 | content: ''; 14 | } 15 | 16 | input { 17 | &[type='text'] { 18 | content: ''; 19 | } 20 | } 21 | 22 | form { 23 | // attribute should be nested 24 | input[type='text'] { 25 | padding: 0; 26 | } 27 | } 28 | 29 | .form { 30 | // attribute should be nested 31 | .class input[type='text'] { 32 | padding: 0; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/sass/force-element-nesting.sass: -------------------------------------------------------------------------------- 1 | // comments denote default rule behaviour 2 | // .new should become a nested selector 3 | h1.new > p 4 | color: #000 5 | 6 | // .test should become a nested selector 7 | .mergeable .test 8 | color: #000 9 | 10 | // shouldn't be nested 11 | .mergeable, .test 12 | color: #000 13 | 14 | // #h1.new should be nested within the parent class 15 | .mergeable #h1.new 16 | color: #000 17 | 18 | // #h1.new should be nested within the parent class 19 | .mergeable 20 | #h1.new 21 | color: #000 22 | 23 | // shouldn't be nested 24 | ul > li 25 | padding: 0 26 | 27 | // p should be nested 28 | div p 29 | padding: 0 30 | 31 | // shouldn't be nested 32 | div > p 33 | margin: 0 34 | 35 | // shouldn't be nested 36 | ul ~ p 37 | color: #ff0000 38 | 39 | // already nested 40 | .test 41 | .bar 42 | color: blue 43 | 44 | // 2 rules should be nested 45 | h1 .class .test 46 | content: '' 47 | 48 | .tester 49 | .class-test 50 | content: '' 51 | &__test h1 52 | content: '' 53 | 54 | // h1 should be nested 55 | input[type="text"] h1 56 | content: '' 57 | -------------------------------------------------------------------------------- /tests/sass/force-pseudo-nesting.sass: -------------------------------------------------------------------------------- 1 | // shouldnt generate a nesting warning 2 | input[type='radio'] 3 | color: red 4 | 5 | // shouldnt generate a nesting warning 6 | div p 7 | padding: 0 8 | 9 | // pseudo class should be nested 10 | p:last-child 11 | margin: 0 12 | 13 | // pseudo class should be nested 14 | p:nth-of-type(2) 15 | margin: 0 16 | 17 | // pseudo class should be nested 18 | input:read-only 19 | content: '' 20 | 21 | // pseudo element should be nested with the parent ident 22 | p::first-line 23 | color: #ff0000 24 | font-variant: small-caps 25 | 26 | .parent 27 | .child 28 | p::first-line 29 | color: #ff0000 30 | 31 | .parent 32 | .child 33 | .sub p::first-line 34 | color: #ff0000 35 | 36 | .parent 37 | .child 38 | .sub p 39 | &::first-line 40 | color: #ff0000 41 | -------------------------------------------------------------------------------- /tests/sass/force-pseudo-nesting.scss: -------------------------------------------------------------------------------- 1 | // shouldnt generate a nesting warning 2 | input[type='radio'] { 3 | color: red; 4 | } 5 | 6 | // shouldnt generate a nesting warning 7 | div p { 8 | padding: 0; 9 | } 10 | 11 | // pseudo class should be nested 12 | p:last-child { 13 | margin: 0; 14 | } 15 | 16 | // pseudo class should be nested 17 | p:nth-of-type(2) { 18 | margin: 0; 19 | } 20 | 21 | 22 | // pseudo class should be nested 23 | input:read-only { 24 | content: ''; 25 | } 26 | 27 | 28 | // pseudo element should be nested with the parent ident 29 | p::first-line { 30 | color: #ff0000; 31 | font-variant: small-caps; 32 | } 33 | 34 | 35 | .parent { 36 | .child { 37 | // pseudo element should be nested with the parent ident 38 | p::first-line { 39 | color: #ff0000; 40 | } 41 | } 42 | } 43 | 44 | .parent { 45 | .child { 46 | // pseudo element should be nested with the parent ident 47 | .sub p::first-line { 48 | color: #ff0000; 49 | } 50 | } 51 | } 52 | 53 | .parent { 54 | .child { 55 | .sub p { 56 | &::first-line { 57 | color: #ff0000; 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /tests/sass/front-matter/front-matter.scss: -------------------------------------------------------------------------------- 1 | --- 2 | # Only the main Sass file needs front matter (the dashes are enough) 3 | --- 4 | 5 | .test { 6 | color: red; 7 | } 8 | -------------------------------------------------------------------------------- /tests/sass/hex-length.sass: -------------------------------------------------------------------------------- 1 | $foo-color: #123 2 | 3 | .foo 4 | background: linear-gradient(top, #cc2, #44d) 5 | color: #fff 6 | 7 | 8 | $bar-color: #112233 9 | 10 | .bar 11 | background: linear-gradient(top, #cccc22, #4444dd) 12 | color: #ffffff 13 | 14 | 15 | // values that can't be shortened are ignored by the style:short rule 16 | 17 | .baz 18 | border-color: #123456 19 | 20 | 21 | // color literals, rgb and hsl values currently don't get returned 22 | // by the AST's color type 23 | 24 | $qux-color: red 25 | $rgb-color: rgb(255, 255, 255) 26 | $rgba-color: rgba(0, 0, 0, .1) 27 | $hsl-color: hsl(40, 50%, 50%) 28 | $hsla-color: hsla(40, 50%, 50%, .3) 29 | -------------------------------------------------------------------------------- /tests/sass/hex-length.scss: -------------------------------------------------------------------------------- 1 | $foo-color: #123; 2 | 3 | .foo { 4 | background: linear-gradient(top, #cc2, #44d); 5 | color: #fff; 6 | } 7 | 8 | $bar-color: #112233; 9 | 10 | .bar { 11 | background: linear-gradient(top, #cccc22, #4444dd); 12 | color: #ffffff; 13 | } 14 | 15 | // values that can't be shortened are ignored by the style:short rule 16 | 17 | .baz { 18 | border-color: #123456; 19 | } 20 | 21 | // color literals, rgb and hsl values currently don't get returned 22 | // by the AST's color type 23 | 24 | $qux-color: red; 25 | $rgb-color: rgb(255, 255, 255); 26 | $rgba-color: rgba(0, 0, 0, .1); 27 | $hsl-color: hsl(40, 50%, 50%); 28 | $hsla-color: hsla(40, 50%, 50%, .3); 29 | -------------------------------------------------------------------------------- /tests/sass/hex-notation.sass: -------------------------------------------------------------------------------- 1 | // numbers only won't match 2 | $foo-color: #123 3 | 4 | .foo 5 | background: linear-gradient(top, #cc2, #44d) 6 | color: #fff 7 | 8 | 9 | $bar-color: #123456 10 | 11 | .bar 12 | background: linear-gradient(top, #CC2, #44D) 13 | color: #FFF 14 | 15 | 16 | .qux 17 | color: #cC2 18 | 19 | 20 | $lower-numbers-color: #123cc2 21 | $upper-lower-color: #CCCCCc 22 | 23 | $map-vals: (mixed: #123Cde) 24 | 25 | // check that only hex colours are being parsed 26 | 27 | $literal-color: red 28 | $rgb-color: rgb(255, 255, 255) 29 | $rgba-color: rgba(0, 0, 0, .1) 30 | $hsl-color: hsl(40, 50%, 50%) 31 | $hsla-color: hsla(40, 50%, 50%, .3) 32 | -------------------------------------------------------------------------------- /tests/sass/hex-notation.scss: -------------------------------------------------------------------------------- 1 | // numbers only won't match 2 | $foo-color: #123; 3 | 4 | .foo { 5 | background: linear-gradient(top, #cc2, #44d); 6 | color: #fff; 7 | } 8 | 9 | $bar-color: #123456; 10 | 11 | .bar { 12 | background: linear-gradient(top, #CC2, #44D); 13 | color: #FFF; 14 | } 15 | 16 | .qux { 17 | color: #cC2; 18 | } 19 | 20 | $lower-numbers-color: #123cc2; 21 | $upper-lower-color: #CCCCCc; 22 | 23 | $map-vals: ( 24 | mixed: #123Cde, 25 | ); 26 | 27 | // check that only hex colours are being parsed 28 | 29 | $literal-color: red; 30 | $rgb-color: rgb(255, 255, 255); 31 | $rgba-color: rgba(0, 0, 0, .1); 32 | $hsl-color: hsl(40, 50%, 50%); 33 | $hsla-color: hsla(40, 50%, 50%, .3); 34 | -------------------------------------------------------------------------------- /tests/sass/id-name-format.sass: -------------------------------------------------------------------------------- 1 | #hyphenated-lowercase 2 | content: '' 3 | 4 | #snake_case 5 | content: '' 6 | 7 | #camelCase 8 | content: '' 9 | 10 | #PascalCase 11 | content: '' 12 | 13 | #Camel_Snake_Case 14 | content: '' 15 | 16 | #SCREAMING_SNAKE_CASE 17 | content: '' 18 | 19 | #_with-leading-underscore 20 | content: '' 21 | 22 | #_does_NOT-fitSTANDARD 23 | @extend #snake_case 24 | 25 | #hyphentated-lowercase 26 | color: blue 27 | 28 | &-with-suffix-extension 29 | color: green 30 | 31 | &-and-another 32 | color: red 33 | 34 | &-INVALID 35 | color: pink 36 | 37 | #one_parent, 38 | #two_parents, 39 | #third-invalid-parent 40 | width: 10px 41 | 42 | &_valid_child, 43 | &-invalid-child 44 | height: 10px 45 | -------------------------------------------------------------------------------- /tests/sass/id-name-format.scss: -------------------------------------------------------------------------------- 1 | #hyphenated-lowercase { 2 | content: ''; 3 | } 4 | 5 | #snake_case { 6 | content: ''; 7 | } 8 | 9 | #camelCase { 10 | content: ''; 11 | } 12 | 13 | #PascalCase { 14 | content: ''; 15 | 16 | #Camel_Snake_Case { 17 | content: ''; 18 | 19 | #SCREAMING_SNAKE_CASE { 20 | content: ''; 21 | } 22 | } 23 | } 24 | 25 | #_with-leading-underscore { 26 | content: ''; 27 | } 28 | 29 | #_does_NOT-fitSTANDARD { 30 | @extend #snake_case; 31 | } 32 | 33 | #hyphentated-lowercase { 34 | color: blue; 35 | 36 | &-with-suffix-extension { 37 | color: green; 38 | 39 | &-and-another { 40 | color: red; 41 | } 42 | } 43 | 44 | &-INVALID { 45 | color: pink; 46 | } 47 | } 48 | 49 | #one_parent, 50 | #two_parents, 51 | #third-invalid-parent { 52 | width: 10px; 53 | 54 | &_valid_child, 55 | &-invalid-child { 56 | height: 10px; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /tests/sass/leading-zero.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | border-radius: .5em 0em, 0.5em 1.0em 3 | height: .6em 4 | width: 100% 5 | 6 | 7 | @if (1 == 0) 8 | $foo: true 9 | -------------------------------------------------------------------------------- /tests/sass/leading-zero.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | border-radius: .5em 0em, 0.5em 1.0em; 3 | height: .6em; 4 | width: 100%; 5 | } 6 | 7 | @if (1 == 0) { 8 | $foo: true; 9 | } 10 | -------------------------------------------------------------------------------- /tests/sass/max-line-length.sass: -------------------------------------------------------------------------------- 1 | .really--long--class-name--that-unfortunately--isnt--very--succint--and-looks-stupid 2 | color: red 3 | 4 | @function($aReallyReallyReallyReallyReallyReallyReallyReallyReallyReallyLongVariableName) 5 | @return 'test' 6 | 7 | // ============================================================================== 8 | // 9 | // This comment is too long clearly, we should probably make sure we have a rule to 10 | // determine when we breach this length 11 | // 12 | // ============================================================================== 13 | 14 | 15 | // ============================================================================= 16 | // 17 | // This comment comment on the other hand should be the perfect length, unless a 18 | // user decides to make their max line length === 79! 19 | // 20 | // ============================================================================= 21 | -------------------------------------------------------------------------------- /tests/sass/max-line-length.scss: -------------------------------------------------------------------------------- 1 | .really--long--class-name--that-unfortunately--isnt--very--succint--and-looks-stupid { 2 | color: red; 3 | } 4 | 5 | @function($aReallyReallyReallyReallyReallyReallyReallyReallyReallyReallyLongVariableName) { 6 | @return 'test'; 7 | } 8 | 9 | // ============================================================================== 10 | // 11 | // This comment is too long clearly, we should probably make sure we have a rule to 12 | // determine when we breach this length 13 | // 14 | // ============================================================================== 15 | 16 | 17 | // ============================================================================= 18 | // 19 | // This comment comment on the other hand should be the perfect length, unless a 20 | // user decides to make their max line length === 79! 21 | // 22 | // ============================================================================= 23 | -------------------------------------------------------------------------------- /tests/sass/mixins-before-declarations.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | +waldo 3 | content: 'baz' 4 | 5 | 6 | .bar 7 | content: 'baz' 8 | +waldo 9 | 10 | 11 | .qux 12 | content: 'baz' 13 | +waldo 14 | margin: 0 15 | 16 | 17 | .breakpoint 18 | content: 'baz' 19 | 20 | +breakpoint(500px) 21 | content: 'waldo' 22 | 23 | 24 | .foo 25 | content: 'where' 26 | 27 | +waldo 28 | 29 | 30 | 31 | &__element 32 | +element 33 | width: 100% 34 | 35 | +mq(500px) 36 | content: 'mq' 37 | 38 | 39 | +waldo 40 | 41 | &--modifier 42 | +foo('yo') 43 | +hello 44 | +test 45 | height: 100px 46 | +test-again 47 | 48 | 49 | // added from issue #230 https://github.com/sasstools/sass-lint/issues/230 50 | 51 | .area-current 52 | $active: #00acac 53 | $background: #2d353c 54 | 55 | +area-menu($active, $background) 56 | 57 | // added from issue #227 https://github.com/sasstools/sass-lint/issues/227 58 | 59 | @include hello 60 | 61 | @media (min-width: 50em) 62 | +hello 63 | 64 | @supports (display: flex) 65 | +hello 66 | 67 | @at-root 68 | +hello 69 | -------------------------------------------------------------------------------- /tests/sass/nesting-depth.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | padding: 5 3 | 4 | .bar 5 | content: 'baz' 6 | 7 | .qux, 8 | .fail 9 | content: 'bob' 10 | 11 | &:hover, 12 | &:active 13 | content: 'fail' 14 | 15 | .bar 16 | content: 'fail' 17 | 18 | .bar 19 | content: 'fail' 20 | 21 | .block 22 | content: 'bar' 23 | 24 | &__element 25 | content: 'bar' 26 | 27 | 28 | &--modifier 29 | content: 'bar' 30 | -------------------------------------------------------------------------------- /tests/sass/nesting-depth.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | padding: 5; 3 | 4 | .bar { 5 | content: 'baz'; 6 | 7 | .qux, 8 | .fail { 9 | content: 'bob'; 10 | 11 | &:hover, 12 | &:active { 13 | content: 'fail'; 14 | 15 | .bar { 16 | content: 'fail'; 17 | } 18 | } 19 | 20 | .bar { 21 | content: 'fail'; 22 | } 23 | } 24 | } 25 | } 26 | 27 | .block { 28 | content: 'bar'; 29 | 30 | &__element { 31 | content: 'bar'; 32 | 33 | 34 | &--modifier { 35 | content: 'bar'; 36 | 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tests/sass/no-at-rule-vendor-prefix.sass: -------------------------------------------------------------------------------- 1 | @-webkit-keyframes test 2 | 0% 3 | top: 0 4 | 5 | @-ms-viewport 6 | orientation: landscape 7 | 8 | @-non-standard 9 | orientation: landscape 10 | 11 | @-non-standard-2 12 | orientation: landscape 13 | 14 | @keyframes test2 15 | 0% 16 | top: 0 17 | 18 | @viewport 19 | orientation: landscape 20 | -------------------------------------------------------------------------------- /tests/sass/no-at-rule-vendor-prefix.scss: -------------------------------------------------------------------------------- 1 | @-webkit-keyframes test { 2 | 0% { 3 | top: 0; 4 | } 5 | } 6 | 7 | @-ms-viewport { 8 | orientation: landscape; 9 | } 10 | 11 | @-non-standard { 12 | orientation: landscape; 13 | } 14 | 15 | @-non-standard-2 { 16 | orientation: landscape; 17 | } 18 | 19 | @keyframes test2 { 20 | 0% { 21 | top: 0; 22 | } 23 | } 24 | 25 | @viewport { 26 | orientation: landscape; 27 | } 28 | -------------------------------------------------------------------------------- /tests/sass/no-color-hex.sass: -------------------------------------------------------------------------------- 1 | $foo-color: #123 2 | 3 | .foo 4 | background: linear-gradient(top, #cc2, #44d) 5 | color: #fff 6 | 7 | 8 | $bar-color: #112233 9 | 10 | .bar 11 | background: linear-gradient(top, #cccc22, #4444dd) 12 | color: #ffffff 13 | 14 | .baz 15 | border-color: #123456 16 | 17 | 18 | // color literals, rgb and hsl values currently don't get returned 19 | // by the AST's color type 20 | 21 | $qux-color: red 22 | $rgb-color: rgb(255, 255, 255) 23 | $rgba-color: rgba(0, 0, 0, .1) 24 | $hsl-color: hsl(40, 50%, 50%) 25 | $hsla-color: hsla(40, 50%, 50%, .3) 26 | -------------------------------------------------------------------------------- /tests/sass/no-color-hex.scss: -------------------------------------------------------------------------------- 1 | $foo-color: #123; 2 | 3 | .foo { 4 | background: linear-gradient(top, #cc2, #44d); 5 | color: #fff; 6 | } 7 | 8 | $bar-color: #112233; 9 | 10 | .bar { 11 | background: linear-gradient(top, #cccc22, #4444dd); 12 | color: #ffffff; 13 | } 14 | 15 | .baz { 16 | border-color: #123456; 17 | } 18 | 19 | // color literals, rgb and hsl values currently don't get returned 20 | // by the AST's color type 21 | 22 | $qux-color: red; 23 | $rgb-color: rgb(255, 255, 255); 24 | $rgba-color: rgba(0, 0, 0, .1); 25 | $hsl-color: hsl(40, 50%, 50%); 26 | $hsla-color: hsla(40, 50%, 50%, .3); 27 | -------------------------------------------------------------------------------- /tests/sass/no-color-keywords.sass: -------------------------------------------------------------------------------- 1 | .literal 2 | color: mediumslateblue 3 | 4 | 5 | .linear-gradient-func 6 | background: linear-gradient(top, #fff, white) 7 | 8 | 9 | .box-shadow 10 | box-shadow: 1px 1px black, 1px 1px black 11 | 12 | 13 | .background 14 | background: 1px solid white 15 | content: 100 16 | 17 | 18 | .hex 19 | color: #fff 20 | 21 | 22 | $colors: ( $red: red, $blue : ( $orange: ( $yellow: yellow ) ) ) 23 | 24 | $literal: mediumslateblue 25 | $hexVar: #fff 26 | 27 | $blue: #0050a0 28 | $brand-primary: $blue 29 | 30 | $other: rgba($blue, 0.3) 31 | 32 | // Issue #717 - rule trips over Sass color function names 33 | $colors: ( 'red': red($color), 'green': green($color), 'blue': blue($color) ) 34 | 35 | $badge-bg: var(--red) 36 | -------------------------------------------------------------------------------- /tests/sass/no-color-keywords.scss: -------------------------------------------------------------------------------- 1 | .literal { 2 | color: mediumslateblue; 3 | } 4 | 5 | .linear-gradient-func { 6 | background: linear-gradient(top, #fff, white); 7 | } 8 | 9 | .box-shadow { 10 | box-shadow: 1px 1px black, 1px 1px black; 11 | } 12 | 13 | .background { 14 | background: 1px solid white; 15 | content: 100; 16 | } 17 | 18 | .hex { 19 | color: #fff; 20 | } 21 | 22 | $colors: ( 23 | $red: red, 24 | $blue : ( 25 | $orange: ( 26 | $yellow: yellow 27 | ) 28 | ) 29 | ); 30 | 31 | $literal: mediumslateblue; 32 | $hexVar: #fff; 33 | 34 | $blue: #0050a0; 35 | $brand-primary: $blue; 36 | 37 | $other: rgba($blue, 0.3); 38 | 39 | // Issue #717 - rule trips over Sass color function names 40 | $colors: ( 41 | 'red': red($color), 42 | 'green': green($color), 43 | 'blue': blue($color) 44 | ); 45 | 46 | $badge-bg: var(--red); 47 | -------------------------------------------------------------------------------- /tests/sass/no-css-comments.sass: -------------------------------------------------------------------------------- 1 | /* Bad */ 2 | .foo 3 | content: ' ' 4 | 5 | 6 | /* 7 | * Test Comment 8 | */ 9 | .bar 10 | content: ' ' 11 | 12 | 13 | // good comment 14 | .baz 15 | content: ' ' 16 | 17 | 18 | /* comment */ 19 | .qux 20 | content: ' ' 21 | 22 | 23 | /*! Single Line Bang Comment */ 24 | .bang-1 25 | content: '' 26 | 27 | 28 | // Multiline 29 | Sass 30 | Comment 31 | .bang-2 32 | content: 'bang' 33 | 34 | 35 | /* 36 | * Multiline Comments are bad 37 | */ 38 | .test 39 | content: ' ' 40 | 41 | 42 | // this is a good comment 43 | .class 44 | content: ' ' 45 | 46 | 47 | // ========= 48 | // This is a good comment 49 | // ========= 50 | .blip 51 | content: ' ' 52 | 53 | 54 | ////////////////// 55 | // This is a good comment 56 | ////////////////// 57 | .blop 58 | content: ' ' 59 | -------------------------------------------------------------------------------- /tests/sass/no-css-comments.scss: -------------------------------------------------------------------------------- 1 | /* Bad */ 2 | .foo { 3 | content: ' '; 4 | } 5 | 6 | /* 7 | * Test Comment 8 | */ 9 | .bar { 10 | content: ' '; 11 | } 12 | 13 | // good comment 14 | .baz { 15 | content: ' '; 16 | } 17 | 18 | /* comment */ 19 | .qux { 20 | content: ' '; 21 | } 22 | 23 | /*! Single Line Bang Comment */ 24 | .bang-1 { 25 | content: ''; 26 | } 27 | 28 | /*! 29 | * Multiline Bang Comment 30 | **/ 31 | .bang-2 { 32 | content: 'bang'; 33 | } 34 | 35 | /* 36 | * Multiline Comments are bad 37 | */ 38 | .test { 39 | content: ' '; 40 | } 41 | 42 | // this is a good comment 43 | .class { 44 | content: ' '; 45 | } 46 | 47 | // ========= 48 | // This is a good comment 49 | // ========= 50 | .blip { 51 | content: ' '; 52 | } 53 | 54 | ////////////////// 55 | // This is a good comment 56 | ////////////////// 57 | .blop { 58 | content: ' '; 59 | } 60 | -------------------------------------------------------------------------------- /tests/sass/no-debug.sass: -------------------------------------------------------------------------------- 1 | @debug 'foo' 2 | 3 | @function foo 4 | @debug 'bar' 5 | 6 | 7 | =baz 8 | @debug 'qux' 9 | -------------------------------------------------------------------------------- /tests/sass/no-debug.scss: -------------------------------------------------------------------------------- 1 | @debug 'foo'; 2 | 3 | @function foo { 4 | @debug 'bar'; 5 | } 6 | 7 | @mixin baz { 8 | @debug 'qux'; 9 | } 10 | -------------------------------------------------------------------------------- /tests/sass/no-disallowed-properties.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | z-index: 10 3 | display: block 4 | .bar 5 | .baz 6 | z-index: 20 7 | 8 | .test 9 | @media (max-width: 100px) 10 | z-index: 10 11 | 12 | =test ($level) 13 | z-index: $level 14 | display: block 15 | 16 | @function myFunc($level) 17 | @return $level * 2 18 | 19 | .func-res 20 | z-index: myFunc(10) 21 | display: block 22 | 23 | interp 24 | z-index: #{20} 25 | display: block 26 | -------------------------------------------------------------------------------- /tests/sass/no-disallowed-properties.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | z-index: 10; 3 | display: block; 4 | 5 | .bar { 6 | .baz { 7 | z-index: 20; 8 | } 9 | } 10 | } 11 | 12 | .test { 13 | @media (max-width: 100px) { 14 | z-index: 10; 15 | } 16 | } 17 | 18 | @mixin test ($level) { 19 | z-index: $level; 20 | display: block; 21 | } 22 | 23 | 24 | @function myFunc($level) { 25 | @return $level * 2; 26 | } 27 | 28 | .func-res { 29 | z-index: myFunc(10); 30 | display: block; 31 | } 32 | 33 | interp { 34 | z-index: #{20}; 35 | display: block; 36 | } 37 | -------------------------------------------------------------------------------- /tests/sass/no-disallowed-property-values.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | z-index: 10 3 | display: block 4 | .bar 5 | .baz 6 | z-index: 20 7 | 8 | .test 9 | @media (max-width: 100px) 10 | z-index: 10 11 | 12 | =test ($level) 13 | z-index: $level 14 | display: block 15 | 16 | @function myFunc($level) 17 | @return $level * 2 18 | 19 | .func-res 20 | z-index: myFunc(10) 21 | display: block 22 | 23 | interp 24 | z-index: #{20} 25 | display: inline 26 | -------------------------------------------------------------------------------- /tests/sass/no-disallowed-property-values.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | z-index: 10; 3 | display: block; 4 | 5 | .bar { 6 | .baz { 7 | z-index: 20; 8 | } 9 | } 10 | } 11 | 12 | .test { 13 | @media (max-width: 100px) { 14 | z-index: 10; 15 | } 16 | } 17 | 18 | @mixin test ($level) { 19 | z-index: $level; 20 | display: block; 21 | } 22 | 23 | 24 | @function myFunc($level) { 25 | @return $level * 2; 26 | } 27 | 28 | .func-res { 29 | z-index: myFunc(10); 30 | display: block; 31 | } 32 | 33 | interp { 34 | z-index: #{20}; 35 | display: inline; 36 | } 37 | -------------------------------------------------------------------------------- /tests/sass/no-duplicate-properties.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | margin: 0 0 15px 3 | padding: 10px 4 | margin: 0 5 | 6 | // excluded display will still fail here due to it not 7 | // following the previous display declaration 8 | .bar 9 | display: block 10 | width: 100% 11 | display: none 12 | 13 | // excluded display will still fail here due to it not 14 | // following the previous display declaration 15 | .baz 16 | display: block 17 | width: 50% 18 | display: none 19 | 20 | .qux 21 | background: rgb(200, 54, 54) 22 | background: rgba(200, 54, 54, 0.5) 23 | 24 | .break 25 | background: rgb(200, 54, 54) 26 | content: 'dec between background' 27 | background: rgba(200, 54, 54, 0.5) 28 | 29 | .display 30 | content: 'display' 31 | display: flex 32 | display: inline-block 33 | 34 | // issue #907 - interpolation/variable in property names 35 | $paint-border-1: top 36 | $paint-border-2: left 37 | 38 | .test 39 | border: $size solid transparent 40 | border-#{$paint-border-1}: $size solid $color 41 | border-#{$paint-border-2}: $size solid $color 42 | border-#{$paint-border-2}: $size solid $color 43 | 44 | // issue #935 - ignore variables 45 | +foo 46 | $i: 0 47 | $i: 1 48 | -------------------------------------------------------------------------------- /tests/sass/no-empty-rulesets.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | 3 | } 4 | 5 | .bar { 6 | content: 'baz'; 7 | 8 | .qux {} 9 | } 10 | 11 | .bar{} 12 | 13 | .baz { 14 | // a comment 15 | /* and 16 | yet 17 | another */ 18 | } 19 | -------------------------------------------------------------------------------- /tests/sass/no-extends.sass: -------------------------------------------------------------------------------- 1 | %foo 2 | color: red 3 | 4 | 5 | .bar 6 | @extend %foo 7 | content: 'baz' 8 | -------------------------------------------------------------------------------- /tests/sass/no-extends.scss: -------------------------------------------------------------------------------- 1 | %foo { 2 | color: red; 3 | } 4 | 5 | .bar { 6 | @extend %foo; 7 | content: 'baz'; 8 | } 9 | -------------------------------------------------------------------------------- /tests/sass/no-ids.sass: -------------------------------------------------------------------------------- 1 | #foo 2 | content: 'bar' 3 | 4 | 5 | .bar#baz 6 | content: 'qux' 7 | -------------------------------------------------------------------------------- /tests/sass/no-ids.scss: -------------------------------------------------------------------------------- 1 | #foo { 2 | content: 'bar'; 3 | } 4 | 5 | .bar#baz { 6 | content: 'qux'; 7 | } 8 | -------------------------------------------------------------------------------- /tests/sass/no-important.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | color: red !important 3 | -------------------------------------------------------------------------------- /tests/sass/no-important.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | color: red !important; 3 | } 4 | -------------------------------------------------------------------------------- /tests/sass/no-media-feature-vendor-prefix.sass: -------------------------------------------------------------------------------- 1 | @media (-webkit-min-device-pixel-ratio: 1) and (max-width: 200px) 2 | 3 | @media (min--mox-device-pixel-ratio: 1) 4 | 5 | @media (-non-standard-min-resolution: 96dpi) 6 | 7 | @media (min-resolution: 96dpi) 8 | -------------------------------------------------------------------------------- /tests/sass/no-media-feature-vendor-prefix.scss: -------------------------------------------------------------------------------- 1 | @media (-webkit-min-device-pixel-ratio: 1) and (max-width: 200px) {} 2 | 3 | @media (min--mox-device-pixel-ratio: 1) {} 4 | 5 | @media (-non-standard-min-resolution: 96dpi) {} 6 | 7 | @media (min-resolution: 96dpi) {} 8 | -------------------------------------------------------------------------------- /tests/sass/no-property-vendor-prefix.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | -webkit-touch-callout: none 3 | -webkit-transform: scale(1) 4 | --custom-prop: 'test' 5 | -------------------------------------------------------------------------------- /tests/sass/no-property-vendor-prefix.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | -webkit-touch-callout: none; 3 | -webkit-transform: scale(1); 4 | --custom-prop: 'test'; 5 | } 6 | -------------------------------------------------------------------------------- /tests/sass/no-qualifying-elements.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | content: 'foo' 3 | 4 | 5 | div.foo 6 | content: 'foo' 7 | 8 | 9 | ul#foo 10 | content: 'foo' 11 | 12 | 13 | input[type='email'] 14 | content: 'foo' 15 | 16 | 17 | .foo.bar 18 | content: 'foo' 19 | 20 | 21 | .foo .bar 22 | content: 'foo' 23 | 24 | 25 | .foo 26 | .bar 27 | content: 'foo' 28 | 29 | 30 | 31 | ul 32 | .foo 33 | content: 'foo' 34 | 35 | 36 | 37 | .foo[type='text'] 38 | content: 'foo' 39 | 40 | 41 | #foo[type='email'] 42 | content: 'foo' 43 | -------------------------------------------------------------------------------- /tests/sass/no-qualifying-elements.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | content: 'foo'; 3 | } 4 | 5 | div.foo { 6 | content: 'foo'; 7 | } 8 | 9 | ul#foo { 10 | content: 'foo'; 11 | } 12 | 13 | input[type='email'] { 14 | content: 'foo'; 15 | } 16 | 17 | .foo.bar { 18 | content: 'foo'; 19 | } 20 | 21 | .foo .bar { 22 | content: 'foo'; 23 | } 24 | 25 | .foo { 26 | .bar { 27 | content: 'foo'; 28 | } 29 | } 30 | 31 | ul { 32 | .foo { 33 | content: 'foo'; 34 | } 35 | } 36 | 37 | .foo[type='text'] { 38 | content: 'foo'; 39 | } 40 | 41 | #foo[type='email'] { 42 | content: 'foo'; 43 | } 44 | -------------------------------------------------------------------------------- /tests/sass/no-selector-vendor-prefix.sass: -------------------------------------------------------------------------------- 1 | input::-moz-placeholder 2 | color: red 3 | 4 | dialog::-webkit-backdrop 5 | background: rgba(255, 0, 0, .25) 6 | 7 | dialog::-webkit-non-standard 8 | background: rgba(255, 0, 0, .25) 9 | 10 | input::placeholder 11 | color: red 12 | 13 | dialog::backdrop 14 | background: rgba(255, 0, 0, .25) 15 | -------------------------------------------------------------------------------- /tests/sass/no-selector-vendor-prefix.scss: -------------------------------------------------------------------------------- 1 | input::-moz-placeholder { color: red; } 2 | dialog::-webkit-backdrop { background: rgba(255, 0, 0, .25); } 3 | dialog::-webkit-non-standard { background: rgba(255, 0, 0, .25); } 4 | 5 | input::placeholder { color: red; } 6 | dialog::backdrop { background: rgba(255, 0, 0, .25); } 7 | -------------------------------------------------------------------------------- /tests/sass/no-trailing-whitespace.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | margin: 1.5rem 3 | 4 | // Two trailing spaces after selector 5 | .bar 6 | margin: 1.5rem 7 | 8 | // Two trailing spaces after property 9 | .baz 10 | margin: 1.5rem 11 | 12 | // Two trailing spaces between rules 13 | .qux 14 | margin: 1.5rem 15 | 16 | 17 | // Trailing tab after selector 18 | .cat 19 | margin: 1.5rem 20 | 21 | // Trailing tab after property 22 | .dog 23 | margin: 1.5rem 24 | 25 | -------------------------------------------------------------------------------- /tests/sass/no-trailing-whitespace.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | margin: 1.5rem; 3 | } 4 | 5 | // Two trailing spaces after selector 6 | .bar { 7 | margin: 1.5rem; 8 | } 9 | 10 | // Two trailing spaces after property 11 | .baz { 12 | margin: 1.5rem; 13 | } 14 | 15 | // Two trailing spaces after rule 16 | .qux { 17 | margin: 1.5rem; 18 | } 19 | 20 | // Trailing tab after selector 21 | .cat { 22 | margin: 1.5rem; 23 | } 24 | 25 | // Trailing tab after property 26 | .dog { 27 | margin: 1.5rem; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /tests/sass/no-trailing-zero.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | margin: 1.5rem 3 | 4 | 5 | .foo 6 | margin: 1.500rem 7 | 8 | 9 | .foo 10 | margin: .5rem 11 | 12 | 13 | .foo 14 | margin: .500rem 15 | 16 | 17 | .foo 18 | margin: 0.25rem 19 | 20 | 21 | .foo 22 | margin: 0.2500rem 23 | 24 | 25 | .foo 26 | margin: 5.0rem 27 | 28 | .foo 29 | margin: 5.00rem 30 | 31 | .foo 32 | margin: .000rem 33 | 34 | .foo 35 | margin: 0.0rem 36 | 37 | .foo 38 | margin: .0rem 39 | 40 | .foo 41 | margin: 0 42 | -------------------------------------------------------------------------------- /tests/sass/no-trailing-zero.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | margin: 1.5rem; 3 | } 4 | 5 | .foo { 6 | margin: 1.500rem; 7 | } 8 | 9 | .foo { 10 | margin: .5rem; 11 | } 12 | 13 | .foo { 14 | margin: .500rem; 15 | } 16 | 17 | .foo { 18 | margin: 0.25rem; 19 | } 20 | 21 | .foo { 22 | margin: 0.2500rem; 23 | } 24 | 25 | .foo { 26 | margin: 5.0rem; 27 | } 28 | 29 | .foo { 30 | margin: 5.00rem; 31 | } 32 | 33 | .foo { 34 | margin: .000rem; 35 | } 36 | 37 | .foo { 38 | margin: 0.0rem; 39 | } 40 | 41 | .foo { 42 | margin: .0rem; 43 | } 44 | 45 | .foo { 46 | margin: 0; 47 | } 48 | -------------------------------------------------------------------------------- /tests/sass/no-transition-all.sass: -------------------------------------------------------------------------------- 1 | .test-single-pass 2 | -webkit-transition: width 2s 3 | transition: width 2s 4 | 5 | .test-single-fail 6 | -webkit-transition: all 2s 7 | transition: all 2s 8 | 9 | .test-mutliple-pass 10 | -webkit-transition: width 2s, height 2s, background-color 2s, -webkit-transform 2s 11 | transition: width 2s, height 2s, background-color 2s, transform 2s 12 | 13 | .test-mutliple-fail 14 | -webkit-transition: all 2s, height 2s, background-color 2s, -webkit-transform 2s 15 | transition: width 2s, height 2s, all 2s, transform 2s 16 | 17 | .test-trans-property-pass 18 | transition-property: none 19 | transition-property: width 20 | transition-property: test_05 21 | transition-property: -specific 22 | transition-property: sliding-vertically 23 | 24 | .test-trans-property-fail 25 | transition-property: all 26 | -------------------------------------------------------------------------------- /tests/sass/no-transition-all.scss: -------------------------------------------------------------------------------- 1 | .test-single-pass { 2 | -webkit-transition: width 2s; 3 | transition: width 2s; 4 | } 5 | 6 | .test-single-fail { 7 | -webkit-transition: all 2s; 8 | transition: all 2s; 9 | } 10 | 11 | .test-mutliple-pass { 12 | -webkit-transition: width 2s, height 2s, background-color 2s, -webkit-transform 2s; 13 | transition: width 2s, height 2s, background-color 2s, transform 2s; 14 | } 15 | 16 | .test-mutliple-fail { 17 | -webkit-transition: all 2s, height 2s, background-color 2s, -webkit-transform 2s; 18 | transition: width 2s, height 2s, all 2s, transform 2s; 19 | } 20 | 21 | .test-trans-property-pass { 22 | transition-property: none; 23 | transition-property: width; 24 | transition-property: test_05; 25 | transition-property: -specific; 26 | transition-property: sliding-vertically; 27 | } 28 | 29 | .test-trans-property-fail { 30 | transition-property: all; 31 | } 32 | -------------------------------------------------------------------------------- /tests/sass/no-universal-selectors.sass: -------------------------------------------------------------------------------- 1 | * 2 | content: 'foo' 3 | 4 | * [lang^=en] 5 | content: 'bar' 6 | 7 | *.warning 8 | content: 'baz' 9 | 10 | *#maincontent 11 | content: 'qux' 12 | 13 | *:before, 14 | *:after 15 | content: 'nurf' 16 | -------------------------------------------------------------------------------- /tests/sass/no-universal-selectors.scss: -------------------------------------------------------------------------------- 1 | * { 2 | content: 'foo'; 3 | } 4 | 5 | * [lang^=en] { 6 | content: 'bar'; 7 | } 8 | 9 | *.warning { 10 | content: 'baz'; 11 | } 12 | 13 | *#maincontent { 14 | content: 'qux'; 15 | } 16 | 17 | *:before, 18 | *:after { 19 | content: 'nurf'; 20 | } 21 | -------------------------------------------------------------------------------- /tests/sass/no-url-domains.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | background-image: url('https://foo.com/img/bar.png') 3 | 4 | 5 | .foo 6 | background-image: url('http://foo.com/img/bar.png') 7 | 8 | 9 | .foo 10 | background-image: url('//foo.com/img/bar.png') 11 | 12 | 13 | .foo 14 | background-image: url('/img/bar.png') 15 | 16 | 17 | .foo 18 | background-image: url('img/bar.png') 19 | 20 | 21 | .foo 22 | background-image: url('bar.png') 23 | 24 | .foo 25 | background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7') 26 | -------------------------------------------------------------------------------- /tests/sass/no-url-domains.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | background-image: url('https://foo.com/img/bar.png'); 3 | } 4 | 5 | .foo { 6 | background-image: url('http://foo.com/img/bar.png'); 7 | } 8 | 9 | .foo { 10 | background-image: url('//foo.com/img/bar.png'); 11 | } 12 | 13 | .foo { 14 | background-image: url('/img/bar.png'); 15 | } 16 | 17 | .foo { 18 | background-image: url('img/bar.png'); 19 | } 20 | 21 | .foo { 22 | background-image: url('bar.png'); 23 | } 24 | 25 | .foo { 26 | background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'); 27 | } 28 | -------------------------------------------------------------------------------- /tests/sass/no-url-protocols.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | background-image: url('https://foo.com/img/bar.png') 3 | 4 | 5 | .foo 6 | background-image: url('http://foo.com/img/bar.png') 7 | 8 | 9 | .foo 10 | background-image: url('//foo.com/img/bar.png') 11 | 12 | 13 | .foo 14 | background-image: url('/img/bar.png') 15 | 16 | 17 | .foo 18 | background-image: url('img/bar.png') 19 | 20 | 21 | .foo 22 | background-image: url('bar.png') 23 | 24 | .foo 25 | background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7') 26 | -------------------------------------------------------------------------------- /tests/sass/no-url-protocols.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | background-image: url('https://foo.com/img/bar.png'); 3 | } 4 | 5 | .foo { 6 | background-image: url('http://foo.com/img/bar.png'); 7 | } 8 | 9 | .foo { 10 | background-image: url('//foo.com/img/bar.png'); 11 | } 12 | 13 | .foo { 14 | background-image: url('/img/bar.png'); 15 | } 16 | 17 | .foo { 18 | background-image: url('img/bar.png'); 19 | } 20 | 21 | .foo { 22 | background-image: url('bar.png'); 23 | } 24 | 25 | .foo { 26 | background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'); 27 | } 28 | -------------------------------------------------------------------------------- /tests/sass/no-value-vendor-prefix.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | display: -webkit-flex 3 | 4 | .bar 5 | max-width: -moz-max-content 6 | 7 | .baz 8 | background: -webkit-linear-gradient(bottom, #000, #fff) 9 | 10 | .non-standard 11 | border: 1px solid -webkit-non-standard 12 | 13 | .var 14 | display: $-webkit-var 15 | 16 | .foo 17 | display: flex 18 | 19 | .bar 20 | max-width: max-content 21 | 22 | .baz 23 | background: linear-gradient(bottom, #000, #fff) 24 | -------------------------------------------------------------------------------- /tests/sass/no-value-vendor-prefix.scss: -------------------------------------------------------------------------------- 1 | .foo { display: -webkit-flex; } 2 | .bar { max-width: -moz-max-content; } 3 | .baz { background: -webkit-linear-gradient(bottom, #000, #fff); } 4 | .non-standard {display: -webkit-non-standard} 5 | .var {display: $-webkit-var} 6 | 7 | .foo { display: flex; } 8 | .bar { max-width: max-content; } 9 | .baz { background: linear-gradient(bottom, #000, #fff); } 10 | -------------------------------------------------------------------------------- /tests/sass/no-warn.sass: -------------------------------------------------------------------------------- 1 | @warn 'foo' 2 | 3 | @function foo 4 | @warn 'bar' 5 | 6 | 7 | =baz 8 | @warn 'qux' 9 | -------------------------------------------------------------------------------- /tests/sass/no-warn.scss: -------------------------------------------------------------------------------- 1 | @warn 'foo'; 2 | 3 | @function foo { 4 | @warn 'bar'; 5 | } 6 | 7 | @mixin baz { 8 | @warn 'qux'; 9 | } 10 | -------------------------------------------------------------------------------- /tests/sass/one-declaration-per-line.scss: -------------------------------------------------------------------------------- 1 | // Should cause issue 2 | .foo { 3 | content: 'baz'; content: 'qux'; 4 | } 5 | 6 | .bar { color: red; content: 'bar'; } 7 | 8 | // Should be ok 9 | .foo { 10 | content: 'bar'; 11 | } 12 | 13 | $foo: adjust-color(rgb(255, 0, 0), $lightness: -20%); 14 | 15 | .bar { 16 | color: adjust-color(rgb(255, 0, 0), $blue: 5); 17 | } 18 | 19 | .baz { 20 | color: scale-color(hsl(120, 70%, 80%), $lightness: 50%); 21 | } 22 | 23 | .qux { 24 | color: change-color(hsl(25, 100%, 80%), $lightness: 40%, $alpha: .8); 25 | } 26 | -------------------------------------------------------------------------------- /tests/sass/parse.scss: -------------------------------------------------------------------------------- 1 | .one { 2 | color: red; 3 | } 4 | 5 | #test 6 | color: blue; 7 | } 8 | -------------------------------------------------------------------------------- /tests/sass/placeholder-in-extend.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | @extend .bar 3 | @extend %baz 4 | -------------------------------------------------------------------------------- /tests/sass/placeholder-in-extend.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | @extend .bar; 3 | 4 | @extend %baz; 5 | } 6 | -------------------------------------------------------------------------------- /tests/sass/placeholder-name-format.sass: -------------------------------------------------------------------------------- 1 | %hyphenated-lowercase 2 | content: '' 3 | 4 | %snake_case 5 | content: '' 6 | 7 | %camelCase 8 | content: '' 9 | 10 | %PascalCase 11 | content: '' 12 | 13 | %Camel_Snake_Case 14 | content: '' 15 | 16 | %SCREAMING_SNAKE_CASE 17 | content: '' 18 | 19 | %_with-leading-underscore 20 | content: '' 21 | 22 | %strictbem 23 | content: '' 24 | 25 | %strictbem_modifier 26 | content: '' 27 | 28 | %strictbem__placeholder 29 | content: '' 30 | 31 | %strictbem__placeholder_modifier 32 | content: '' 33 | 34 | %strictbem_modifier__placeholder 35 | content: '' 36 | 37 | %hyphenatedbem--modifier 38 | content: '' 39 | 40 | %hyphenatedbem__placeholder 41 | content: '' 42 | 43 | %hyphenatedbem__placeholder--modifier 44 | content: '' 45 | 46 | %hyphenatedbem--modifier__placeholder 47 | content: '' 48 | 49 | %_does_NOT-fitSTANDARD 50 | content: '' 51 | 52 | .class 53 | @extend %snake_case 54 | 55 | // Issue: https://github.com/sasstools/sass-lint/issues/625 56 | // variables/interpolation should be ignored 57 | %#{$var} 58 | content: '' 59 | -------------------------------------------------------------------------------- /tests/sass/placeholder-name-format.scss: -------------------------------------------------------------------------------- 1 | %hyphenated-lowercase { 2 | content: ''; 3 | } 4 | 5 | %snake_case { 6 | content: ''; 7 | } 8 | 9 | %camelCase { 10 | content: ''; 11 | } 12 | 13 | %PascalCase { 14 | content: ''; 15 | } 16 | 17 | %Camel_Snake_Case { 18 | content: ''; 19 | } 20 | 21 | %SCREAMING_SNAKE_CASE { 22 | content: ''; 23 | } 24 | 25 | %_with-leading-underscore { 26 | content: ''; 27 | } 28 | 29 | %strictbem { 30 | content: ''; 31 | } 32 | 33 | %strictbem_placeholder { 34 | content: ''; 35 | } 36 | 37 | %strictbem__mixin { 38 | content: ''; 39 | } 40 | 41 | %strictbem__mixin_placeholder { 42 | content: ''; 43 | } 44 | 45 | %strictbem_placeholder__mixin { 46 | content: ''; 47 | } 48 | 49 | %hyphenatedbem--placeholder { 50 | content: ''; 51 | } 52 | 53 | %hyphenatedbem__mixin { 54 | content: ''; 55 | } 56 | 57 | %hyphenatedbem__mixin--placeholder { 58 | content: ''; 59 | } 60 | 61 | %hyphenatedbem--placeholder__mixin { 62 | content: ''; 63 | } 64 | 65 | %_does_NOT-fitSTANDARD { 66 | content: ''; 67 | } 68 | 69 | .class { 70 | @extend %snake_case; 71 | } 72 | 73 | // Issue: https://github.com/sasstools/sass-lint/issues/625 74 | // variables/interpolation should be ignored 75 | %#{$var} { 76 | content: ''; 77 | } 78 | -------------------------------------------------------------------------------- /tests/sass/property-sort-order.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | height: 100vh 3 | display: block 4 | width: 100vw 5 | border: 1px 6 | 7 | .bar 8 | width: 50vw 9 | content: 'baz' 10 | border: 1px 11 | height: 100vw 12 | 13 | 14 | .other-property 15 | composes: heading 16 | height: 100vh 17 | display: block 18 | width: 100vw 19 | border: 1px 20 | 21 | .other-property-new 22 | height: 100vh 23 | display: block 24 | width: 100vw 25 | border: 1px 26 | composes: heading 27 | 28 | @function test($foo) 29 | // The line below causes the problem 30 | $bar: $foo 31 | 32 | 33 | =placeholder 34 | $placeholders: ':-webkit-input' ':-moz' '-moz' '-ms-input' 35 | @each $placeholder in $placeholders 36 | 37 | &:#{$placeholder}-placeholder 38 | @content 39 | 40 | 41 | 42 | 43 | @function em($target, $context: $base-font-size) 44 | @if not unitless($target) 45 | $target: strip-units($target) 46 | 47 | @if not unitless($context) 48 | $context: strip-units($context) 49 | 50 | @if $target == 0 @return 0 51 | @return $target / $context + 0em 52 | -------------------------------------------------------------------------------- /tests/sass/property-sort-order.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | height: 100vh; 3 | display: block; 4 | width: 100vw; 5 | border: 1px; 6 | 7 | .bar { 8 | width: 50vw; 9 | content: 'baz'; 10 | border: 1px; 11 | height: 100vw; 12 | } 13 | } 14 | 15 | .other-property { 16 | composes: heading; 17 | height: 100vh; 18 | display: block; 19 | width: 100vw; 20 | border: 1px; 21 | } 22 | 23 | .other-property-new { 24 | height: 100vh; 25 | display: block; 26 | width: 100vw; 27 | border: 1px; 28 | composes: heading; 29 | } 30 | 31 | @function test($foo) { 32 | // The line below causes the problem 33 | $bar: $foo; 34 | } 35 | 36 | @mixin placeholder { 37 | $placeholders: ':-webkit-input' ':-moz' '-moz' '-ms-input'; 38 | @each $placeholder in $placeholders { 39 | 40 | &:#{$placeholder}-placeholder { 41 | @content; 42 | } 43 | } 44 | } 45 | 46 | @function em($target, $context: $base-font-size) { 47 | @if not unitless($target) { 48 | $target: strip-units($target); 49 | } 50 | @if not unitless($context) { 51 | $context: strip-units($context); 52 | } 53 | @if $target == 0 { @return 0 } 54 | @return $target / $context + 0em; 55 | } 56 | -------------------------------------------------------------------------------- /tests/sass/property-units.sass: -------------------------------------------------------------------------------- 1 | .literal 2 | height: 3em 3 | 4 | .literal-property 5 | width: 3px 6 | 7 | .box-shadow 8 | box-shadow: 1em 1em black, 1em 1em black 9 | 10 | .background 11 | background: 1em solid white 12 | 13 | .function 14 | color: test(2em) 15 | 16 | // using literals as property names 17 | $sizes: 2em 18 | 19 | .literal-property 20 | width: 3px 21 | height: 0 22 | .red 23 | width: 4 24 | height: 5px 25 | -------------------------------------------------------------------------------- /tests/sass/property-units.scss: -------------------------------------------------------------------------------- 1 | .literal { 2 | height: 3em; 3 | } 4 | 5 | .literal-property { 6 | width: 3px; 7 | } 8 | 9 | .box-shadow { 10 | box-shadow: 1em 1em black, 1em 1em black; 11 | } 12 | 13 | .background { 14 | background: 1em solid white; 15 | } 16 | 17 | .function { 18 | color: test(2em); 19 | } 20 | 21 | // using literals as property names 22 | $sizes: ( 23 | small: 2em, 24 | big : ( 25 | important: 2rem 26 | ) 27 | ); 28 | 29 | .literal-property { 30 | width: 3px; 31 | height: 0; 32 | 33 | .red { 34 | width: 4; 35 | height: 5px; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/sass/quotes.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | content: 'hello' 3 | 4 | 5 | .bar 6 | content: "hello" 7 | 8 | 9 | .baz 10 | background-image: url('/foo/img.png') 11 | 12 | 13 | .qux 14 | background-image: url("/foo/img.png") 15 | -------------------------------------------------------------------------------- /tests/sass/quotes.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | content: 'hello'; 3 | } 4 | 5 | .bar { 6 | content: "hello"; 7 | } 8 | 9 | .baz { 10 | background-image: url('/foo/img.png'); 11 | } 12 | 13 | .qux { 14 | background-image: url("/foo/img.png"); 15 | } 16 | -------------------------------------------------------------------------------- /tests/sass/ruleToggler-disable-a-block.sass: -------------------------------------------------------------------------------- 1 | p 2 | // sass-lint:disable-block a 3 | -------------------------------------------------------------------------------- /tests/sass/ruleToggler-disable-a-block.scss: -------------------------------------------------------------------------------- 1 | p { 2 | // sass-lint:disable-block a 3 | } 4 | -------------------------------------------------------------------------------- /tests/sass/ruleToggler-disable-a-line.sass: -------------------------------------------------------------------------------- 1 | p 2 | border-color: red // sass-lint:disable-line a 3 | -------------------------------------------------------------------------------- /tests/sass/ruleToggler-disable-a-line.scss: -------------------------------------------------------------------------------- 1 | p { 2 | border-color: red; // sass-lint:disable-line a 3 | } 4 | -------------------------------------------------------------------------------- /tests/sass/ruleToggler-disable-a-rule.sass: -------------------------------------------------------------------------------- 1 | // sass-lint:disable a 2 | -------------------------------------------------------------------------------- /tests/sass/ruleToggler-disable-a-rule.scss: -------------------------------------------------------------------------------- 1 | // sass-lint:disable a 2 | -------------------------------------------------------------------------------- /tests/sass/ruleToggler-disable-all-then-reenable.sass: -------------------------------------------------------------------------------- 1 | // sass-lint:disable-all 2 | 3 | // sass-lint:enable-all 4 | -------------------------------------------------------------------------------- /tests/sass/ruleToggler-disable-all-then-reenable.scss: -------------------------------------------------------------------------------- 1 | // sass-lint:disable-all 2 | 3 | // sass-lint:enable-all 4 | -------------------------------------------------------------------------------- /tests/sass/ruleToggler-disable-all.sass: -------------------------------------------------------------------------------- 1 | // sass-lint:disable-all 2 | -------------------------------------------------------------------------------- /tests/sass/ruleToggler-disable-all.scss: -------------------------------------------------------------------------------- 1 | // sass-lint:disable-all 2 | -------------------------------------------------------------------------------- /tests/sass/ruleToggler-disable-multiple-rules.sass: -------------------------------------------------------------------------------- 1 | // sass-lint:disable a b, c d 2 | -------------------------------------------------------------------------------- /tests/sass/ruleToggler-disable-multiple-rules.scss: -------------------------------------------------------------------------------- 1 | // sass-lint:disable a b, c d 2 | -------------------------------------------------------------------------------- /tests/sass/ruleToggler-disable-next-line.sass: -------------------------------------------------------------------------------- 1 | p 2 | // sass-lint:disable-next-line a 3 | border-color: red 4 | -------------------------------------------------------------------------------- /tests/sass/ruleToggler-disable-next-line.scss: -------------------------------------------------------------------------------- 1 | p { 2 | // sass-lint:disable-next-line a 3 | border-color: red; 4 | } 5 | -------------------------------------------------------------------------------- /tests/sass/ruleToggler-disable-then-enable.sass: -------------------------------------------------------------------------------- 1 | p 2 | // sass-lint:disable a 3 | border: none 4 | // sass-lint:enable a 5 | color: blue 6 | -------------------------------------------------------------------------------- /tests/sass/ruleToggler-disable-then-enable.scss: -------------------------------------------------------------------------------- 1 | p { 2 | // sass-lint:disable a 3 | border: none; 4 | // sass-lint:enable a 5 | color: blue; 6 | } 7 | -------------------------------------------------------------------------------- /tests/sass/ruleToggler-empty-comment.sass: -------------------------------------------------------------------------------- 1 | p 2 | /**/ 3 | -------------------------------------------------------------------------------- /tests/sass/ruleToggler-empty-comment.scss: -------------------------------------------------------------------------------- 1 | p { 2 | /**/ 3 | } -------------------------------------------------------------------------------- /tests/sass/ruleToggler-guarantee-order.sass: -------------------------------------------------------------------------------- 1 | p 2 | // sass-lint:disable a 3 | border: 0 4 | // sass-lint:disable-block a 5 | font-size: 100% 6 | 7 | a 8 | // sass-lint:disable a 9 | border: 0 10 | // sass-lint:disable-block a 11 | font-size: 100% 12 | 13 | li 14 | /* sass-lint:disable a 15 | /* sass-lint:disable a 16 | border: 0 17 | font-size: 100% 18 | -------------------------------------------------------------------------------- /tests/sass/ruleToggler-guarantee-order.scss: -------------------------------------------------------------------------------- 1 | p { 2 | // sass-lint:disable a 3 | border: 0; 4 | // sass-lint:disable-block a 5 | font-size: 100%; 6 | } 7 | 8 | a { // sass-lint:disable a 9 | border: 0; 10 | // sass-lint:disable-block a 11 | font-size: 100%; 12 | } 13 | 14 | li { /* sass-lint:disable a */ /* sass-lint:disable a */ 15 | border: 0; 16 | font-size: 100%; 17 | } 18 | -------------------------------------------------------------------------------- /tests/sass/ruleToggler-ignore-unknown.sass: -------------------------------------------------------------------------------- 1 | p 2 | //sass-lint:random a 3 | -------------------------------------------------------------------------------- /tests/sass/ruleToggler-ignore-unknown.scss: -------------------------------------------------------------------------------- 1 | p { 2 | //sass-lint:random a 3 | } -------------------------------------------------------------------------------- /tests/sass/selector-helpers/selector-helpers.scss: -------------------------------------------------------------------------------- 1 | .test{ 2 | color: red; 3 | } 4 | 5 | #test{ 6 | color: red; 7 | } 8 | 9 | %test { 10 | color: red; 11 | } 12 | 13 | .#{test} { 14 | color: red 15 | } 16 | 17 | .test, #test { 18 | color: red; 19 | } 20 | 21 | input[type="text"] { 22 | color: red; 23 | } 24 | 25 | .test > li { 26 | color: red; 27 | } 28 | 29 | span[lang~=en-us] { 30 | color: red; 31 | } 32 | 33 | .block__element-one { 34 | color: red; 35 | } 36 | 37 | @media (max-width: 200px) { 38 | color: red; 39 | } 40 | 41 | ##{$id} { 42 | color: red; 43 | } 44 | 45 | .right-element::-ms-backdrop { 46 | content: "right-prefixed-element"; 47 | } 48 | 49 | .wrong-element:selection { 50 | content: "wrong-element"; 51 | } 52 | 53 | p:nth-of-type(2) { 54 | margin: 0; 55 | } 56 | 57 | .test { 58 | &__test { 59 | color: red; 60 | } 61 | } 62 | 63 | tr:nth-child(even) { 64 | background: lighten($theme-color-primary, 50%); 65 | } 66 | tr:nth-child(odd) { 67 | background: #FFFFFF; 68 | } 69 | -------------------------------------------------------------------------------- /tests/sass/single-line-per-selector.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | content: 'foo' 3 | 4 | 5 | .foo.boo 6 | content: 'foo' 7 | 8 | 9 | .foo, .boo 10 | content: 'foo' 11 | 12 | 13 | .foo,.boo 14 | content: 'foo' 15 | 16 | 17 | .foo, 18 | .boo 19 | content: 'foo' 20 | 21 | 22 | .foo > a,.bar 23 | content: 'baz' 24 | 25 | 26 | .foo, 27 | .bar 28 | content: 'baz' 29 | 30 | .baz, 31 | .qux 32 | content: 'qux' 33 | 34 | 35 | .fail, .blog 36 | content: 'cats' 37 | 38 | 39 | .where, 40 | .waldo, .qux 41 | content: 'found' 42 | 43 | .foo 44 | .bar &, 45 | .baz & 46 | content: 'foo' 47 | 48 | .foo 49 | .bar &, .baz & 50 | content: 'foo' 51 | 52 | // Issue #789 - Issue with comments being warned as selector content on single lines 53 | button, 54 | html, 55 | html input[type='button'], // 6 56 | input[type='reset'], 57 | input[type='submit'] 58 | -webkit-appearance: button; // 7 59 | cursor: pointer; // 8 60 | -------------------------------------------------------------------------------- /tests/sass/single-line-per-selector.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | content: 'foo'; 3 | } 4 | 5 | .foo.boo { 6 | content: 'foo'; 7 | } 8 | 9 | .foo, .boo { 10 | content: 'foo'; 11 | } 12 | 13 | .foo,.boo { 14 | content: 'foo'; 15 | } 16 | 17 | .foo, 18 | .boo { 19 | content: 'foo'; 20 | } 21 | 22 | .foo > a,.bar { 23 | content: 'baz'; 24 | } 25 | 26 | .foo, 27 | .bar { 28 | content: 'baz'; 29 | 30 | .baz, 31 | .qux { 32 | content: 'qux'; 33 | } 34 | 35 | .fail, .blog { 36 | content: 'cats'; 37 | } 38 | 39 | .where, 40 | .waldo, .qux { 41 | content: 'found'; 42 | } 43 | } 44 | 45 | .foo { 46 | .bar &, 47 | .baz & { 48 | content: 'foo'; 49 | } 50 | } 51 | 52 | .foo { 53 | .bar &, .baz & { 54 | content: 'foo'; 55 | } 56 | } 57 | 58 | // Issue #789 - Issue with comments being warned as selector content on single lines 59 | button, 60 | html, 61 | html input[type='button'], // 6 62 | input[type='reset'], 63 | input[type='submit'] { 64 | -webkit-appearance: button; // 7 65 | cursor: pointer; // 8 66 | } 67 | -------------------------------------------------------------------------------- /tests/sass/space-after-colon.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | content: 'foo' 3 | 4 | 5 | .bar 6 | content:'bar' 7 | 8 | 9 | .baz 10 | @media (max-width: 50em) and (orientation:landscape) 11 | content: 'baz' 12 | 13 | 14 | 15 | $qux: 'qux' 16 | $norf:'norf' 17 | 18 | .foo 19 | @at-root button#{&}:hover 20 | 21 | .foo:hover 22 | +test 23 | -------------------------------------------------------------------------------- /tests/sass/space-after-colon.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | content: 'foo'; 3 | } 4 | 5 | .bar { 6 | content:'bar'; 7 | } 8 | 9 | .baz { 10 | @media (max-width: 50em) and (orientation:landscape) { 11 | content: 'baz'; 12 | } 13 | } 14 | 15 | $qux: 'qux'; 16 | $norf:'norf'; 17 | 18 | .foo { 19 | @at-root button#{&}:hover { 20 | } 21 | } 22 | 23 | .foo:hover { 24 | @include test; 25 | } 26 | 27 | $map: { 28 | test:'red', 29 | other: blue, 30 | } 31 | -------------------------------------------------------------------------------- /tests/sass/space-after-comma.sass: -------------------------------------------------------------------------------- 1 | h1,h2 2 | content: 'foo' 3 | 4 | 5 | h3, h4 6 | content: 'foo' 7 | 8 | 9 | h5, 10 | h6 11 | content: 'foo' 12 | 13 | 14 | .foo 15 | box-shadow: 1px 1px black,1px 1px black 16 | 17 | 18 | .foo 19 | box-shadow: 1px 1px black, 1px 1px black 20 | 21 | 22 | .bar 23 | @include mixin('foo','bar') 24 | 25 | 26 | .bar 27 | @include mixin('foo', 'bar') 28 | 29 | 30 | @function foo($bar,$baz) 31 | @return $bar * $baz 32 | 33 | 34 | @function foo($bar, $baz) 35 | @return $bar * $baz 36 | 37 | 38 | =foo( 39 | $foo: true, 40 | $bar: false 41 | ) 42 | content: 'foo' 43 | 44 | 45 | =foo( 46 | $foo: true, // Foo 47 | $bar: false /* Bar */ 48 | ) 49 | content: 'foo' 50 | -------------------------------------------------------------------------------- /tests/sass/space-after-comma.scss: -------------------------------------------------------------------------------- 1 | h1,h2 { 2 | content: 'foo'; 3 | } 4 | 5 | h1, h2 { 6 | content: 'foo'; 7 | } 8 | 9 | h1, 10 | h2 { 11 | content: 'foo'; 12 | } 13 | 14 | .foo { 15 | box-shadow: 1px 1px black,1px 1px black; 16 | } 17 | 18 | .foo { 19 | box-shadow: 1px 1px black, 1px 1px black; 20 | } 21 | 22 | .bar { 23 | @include mixin('foo','bar'); 24 | } 25 | 26 | .bar { 27 | @include mixin('foo', 'bar'); 28 | } 29 | 30 | @function foo($bar,$baz) { 31 | @return $bar * $baz; 32 | } 33 | 34 | @function foo($bar, $baz) { 35 | @return $bar * $baz; 36 | } 37 | 38 | @mixin foo( 39 | $foo: true, 40 | $bar: false 41 | ) { 42 | content: 'foo'; 43 | } 44 | 45 | @mixin foo( 46 | $foo: true, // Foo 47 | $bar: false /* Bar */ 48 | ) { 49 | content: 'foo'; 50 | } 51 | -------------------------------------------------------------------------------- /tests/sass/space-before-bang.sass: -------------------------------------------------------------------------------- 1 | // Important 2 | 3 | .foo 4 | color: red!important 5 | 6 | 7 | .bar 8 | color: orange !important 9 | 10 | 11 | .baz 12 | color: green! important 13 | 14 | 15 | .quz 16 | color: pink ! important 17 | 18 | 19 | // Default 20 | 21 | $foo: red!default 22 | 23 | $foo: orange !default 24 | 25 | $foo: blue! default 26 | 27 | $foo: green ! default 28 | 29 | =testcase($important: null) 30 | @if $important == true 31 | $important: !important 32 | 33 | =testcaseFail($important: null) 34 | @if $important == true 35 | $important:!important 36 | 37 | =testcase($important: null) 38 | @if $important == true 39 | $important: ! important 40 | 41 | =testcaseFail($important: null) 42 | @if $important == true 43 | $important:! important 44 | 45 | =testcase($important: null) 46 | @if $important == true 47 | $color: red !default 48 | 49 | =testcaseFail($important: null) 50 | @if $important == true 51 | $color: red!default 52 | 53 | =testcaseFail($important: null) 54 | @if $important == true 55 | $color: red ! default 56 | 57 | =testcaseFail($important: null) 58 | @if $important == true 59 | $color: red! default 60 | -------------------------------------------------------------------------------- /tests/sass/space-before-bang.scss: -------------------------------------------------------------------------------- 1 | // Important 2 | 3 | .foo { 4 | color:red!important; 5 | } 6 | 7 | .bar { 8 | color: orange !important; 9 | } 10 | 11 | .baz { 12 | color: green! important; 13 | } 14 | 15 | .quz { 16 | color: pink ! important; 17 | } 18 | 19 | // Default 20 | 21 | $foo: red!default; 22 | 23 | $foo: red !default; 24 | 25 | $foo: red! default; 26 | 27 | $foo: red ! default; 28 | 29 | @mixin testcase($important: null) { 30 | @if ($important == true) {$important: !important;} 31 | } 32 | 33 | @mixin testcaseFail($important: null) { 34 | @if ($important == true) {$important:!important;} 35 | } 36 | 37 | @mixin testcase($important: null) { 38 | @if ($important == true) {$important: ! important;} 39 | } 40 | 41 | @mixin testcaseFail($important: null) { 42 | @if ($important == true) {$important:! important;} 43 | } 44 | 45 | @mixin testcase($important: null) { 46 | @if ($important == true) {$color: red !default;} 47 | } 48 | 49 | @mixin testcaseFail($important: null) { 50 | @if ($important == true) {$color: red!default;} 51 | } 52 | 53 | @mixin testcase($important: null) { 54 | @if ($important == true) {$color: red ! default;} 55 | } 56 | 57 | @mixin testcaseFail($important: null) { 58 | @if ($important == true) {$color: red! default;} 59 | } 60 | -------------------------------------------------------------------------------- /tests/sass/space-before-brace.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | content: 'bar'; 3 | } 4 | 5 | .bar{ 6 | content: 'baz'; 7 | } 8 | 9 | .qux { 10 | content: 'bar'; 11 | } 12 | 13 | @mixin foo { 14 | content: 'qux'; 15 | } 16 | 17 | @mixin bar{ 18 | content: 'qux'; 19 | } 20 | 21 | .qux { 22 | content: 'bar'; 23 | font:{ 24 | family: fantasy; 25 | } 26 | @include breakpoint{ 27 | content: bar; 28 | font: { 29 | family: fantasy; 30 | } 31 | } 32 | } 33 | 34 | 35 | .other { 36 | content: 'bar'; 37 | font: { 38 | family: fantasy; 39 | } 40 | @include breakpoint { 41 | content: bar; 42 | font:{ 43 | family: fantasy; 44 | } 45 | } 46 | } 47 | 48 | .selector { 49 | content: ''; 50 | 51 | .mergeable { 52 | font: { 53 | family: fantasy; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tests/sass/space-before-colon.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | content :'foo' 3 | 4 | 5 | .bar 6 | content:'bar' 7 | 8 | 9 | .baz 10 | @media (max-width :50em) and (orientation:landscape) 11 | content: 'baz' 12 | 13 | 14 | 15 | $qux: 'qux' 16 | $norf :'norf' 17 | -------------------------------------------------------------------------------- /tests/sass/space-before-colon.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | content :'foo'; 3 | } 4 | 5 | .bar { 6 | content:'bar'; 7 | } 8 | 9 | .baz { 10 | @media (max-width :50em) and (orientation:landscape) { 11 | content: 'baz'; 12 | } 13 | } 14 | 15 | $qux: 'qux'; 16 | $norf :'norf'; 17 | -------------------------------------------------------------------------------- /tests/sass/space-between-parens.sass: -------------------------------------------------------------------------------- 1 | @function foo( $bar) 2 | @return $bar 3 | 4 | 5 | @function baz() 6 | @return false 7 | 8 | 9 | 10 | =bar ($baz ) 11 | content: $baz 12 | 13 | 14 | .foo 15 | +bar( 'Hello' ) 16 | content: foo('bar') 17 | width: calc( 100% - 10px) 18 | 19 | // Top level mixin 20 | +hello( 21 | $foo, 22 | $bar, 23 | $baz 24 | ) 25 | 26 | .foo 27 | // Nested Mixin 28 | +hello( 29 | $foo, 30 | $bar, 31 | $baz 32 | ) 33 | 34 | // CSS built-in function 35 | background: transparent linear-gradient( 36 | to bottom, 37 | #ff0000 0%, 38 | #00ff00 40%, 39 | #0000ff 40% 40 | ) 41 | 42 | // User-defined function 43 | content: goodbye( 44 | $foo, 45 | $bar 46 | ) 47 | -------------------------------------------------------------------------------- /tests/sass/space-between-parens.scss: -------------------------------------------------------------------------------- 1 | @function foo( $bar) { 2 | @return $bar; 3 | } 4 | 5 | @function baz() { 6 | 7 | } 8 | 9 | @mixin bar ($baz ) { 10 | content: $baz; 11 | } 12 | 13 | .foo { 14 | @include bar( 'Hello' ); 15 | content: foo('bar'); 16 | width: calc( 100% - 10px); 17 | } 18 | 19 | // Top level mixin 20 | @include hello( 21 | $foo, 22 | $bar, 23 | $baz 24 | ); 25 | 26 | .foo { 27 | // Nested Mixin 28 | @include hello( 29 | $foo, 30 | $bar, 31 | $baz 32 | ); 33 | 34 | // CSS built-in function 35 | background: transparent linear-gradient( 36 | to bottom, 37 | #ff0000 0%, 38 | #00ff00 40%, 39 | #0000ff 40% 40 | ); 41 | 42 | // User-defined function 43 | content: goodbye( 44 | $foo, 45 | $bar 46 | ); 47 | } 48 | -------------------------------------------------------------------------------- /tests/sass/success.scss: -------------------------------------------------------------------------------- 1 | .one { 2 | margin-top: 0; 3 | } 4 | -------------------------------------------------------------------------------- /tests/sass/trailing-semicolon.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | content: 'bar' 3 | } 4 | 5 | .bar { 6 | content: 'qux';; 7 | padding: 0 8 | 9 | .qux { 10 | float: left;; 11 | content: 'waldo' 12 | } 13 | } 14 | 15 | .qux { 16 | font: { 17 | family: 'Arial'; 18 | weight: bold; 19 | size: 2rem; 20 | } 21 | } 22 | 23 | .baz { 24 | font: { 25 | family: 'Arial';; 26 | weight: bold; 27 | size: 2rem 28 | } 29 | } 30 | 31 | .norf { 32 | border: { 33 | top: { 34 | color: red;; 35 | 36 | left: { 37 | radius: 5px 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/sass/url-quotes.sass: -------------------------------------------------------------------------------- 1 | $foo: 'foo.png' 2 | 3 | .foo 4 | background-image: url('foo.png') 5 | 6 | 7 | .bar 8 | background-image: url(foo.png) 9 | 10 | 11 | .baz 12 | background-image: url($foo) 13 | 14 | 15 | .qux 16 | background-image: url('bar/' + $foo) 17 | -------------------------------------------------------------------------------- /tests/sass/url-quotes.scss: -------------------------------------------------------------------------------- 1 | $foo: 'foo.png'; 2 | 3 | .foo { 4 | background-image: url('foo.png'); 5 | } 6 | 7 | .bar { 8 | background-image: url(foo.png); 9 | } 10 | 11 | .baz { 12 | background-image: url($foo); 13 | } 14 | 15 | .qux { 16 | background-image: url('bar/' + $foo); 17 | } 18 | -------------------------------------------------------------------------------- /tests/sass/variable-for-property.sass: -------------------------------------------------------------------------------- 1 | .foo 2 | content: $content 3 | margin: $margin 4 | 5 | &__element 6 | margin: $margin 7 | 8 | 9 | 10 | =blue() 11 | margin: $margin 12 | 13 | 14 | .bar 15 | content: ' ' 16 | margin: 0 17 | 18 | &__element 19 | margin: 0 20 | 21 | 22 | 23 | =red() 24 | margin: 0 25 | 26 | .test 27 | background: inherit 28 | background: initial 29 | background: transparent 30 | background: none 31 | 32 | // Issue #714 - !important and spaces were classed as erroneous value types 33 | .non-issue 34 | color: $gray-chateau !important 35 | 36 | .issue 37 | color: red !important 38 | 39 | .test 40 | color: map-get($blue) 41 | 42 | .interp-test 43 | color: #{var} 44 | 45 | // ensure interp is not flagged 46 | 47 | .func-name-test 48 | color: my-map-func(blue, light) 49 | 50 | .custom-prop 51 | // ensure custom properties are valid 52 | color: var(--my-prop) 53 | -------------------------------------------------------------------------------- /tests/sass/variable-for-property.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | content: $content; 3 | margin: $margin; 4 | 5 | &__element { 6 | margin: $margin; 7 | } 8 | } 9 | 10 | @mixin blue() { 11 | margin: $margin; 12 | } 13 | 14 | .bar { 15 | content: ' '; 16 | margin: 0; 17 | 18 | &__element { 19 | margin: 0; 20 | } 21 | } 22 | 23 | @mixin red() { 24 | margin: 0; 25 | } 26 | 27 | .test { 28 | background: inherit; 29 | background: initial; 30 | background: transparent; 31 | background: none; 32 | } 33 | 34 | // Issue #714 - !important and spaces were classed as erroneous value types 35 | .t-neutral { 36 | color: $gray-chateau !important; 37 | } 38 | 39 | .t-neutral { 40 | color: red !important; 41 | } 42 | 43 | .test { 44 | color: map-get($blue); 45 | } 46 | 47 | .interp-test { 48 | color: #{var}; // ensure interp is not flagged 49 | } 50 | 51 | .func-name-test { 52 | color: my-map-func(blue, light); 53 | } 54 | 55 | .custom-prop { 56 | color: var(--my-prop); // ensure custom properties are valid 57 | } 58 | -------------------------------------------------------------------------------- /tests/sass/variable-name-format.sass: -------------------------------------------------------------------------------- 1 | $kabab-case: 1 2 | $snake_case: 1 3 | $camelCase: 1 4 | $PascalCase: 1 5 | $Camel_Snake_Case: 1 6 | $SCREAMING_SNAKE_CASE: 1 7 | $_with-leading-underscore: 1 8 | 9 | $strictbem: 1 10 | $strictbem__variable: 1 11 | $strictbem__variable_modifier: 1 12 | $strictbem_modifier__variable: 1 13 | $hyphenatedbem--modifier: 1 14 | $hyphenatedbem__variable: 1 15 | $hyphenatedbem__variable--modifier: 1 16 | $hyphenatedbem--modifier__variable: 1 17 | 18 | $_does_NOT-fitSTANDARD: 1 19 | 20 | .class 21 | width: $snake_case 22 | 23 | // Issue #901 - operators not recognized as separate tokens by gonzales-pe 24 | .content-main 25 | padding: $mobile-site-gutter*1.5 26 | -------------------------------------------------------------------------------- /tests/sass/variable-name-format.scss: -------------------------------------------------------------------------------- 1 | $kabab-case: 1; 2 | $snake_case: 1; 3 | $camelCase: 1; 4 | $PascalCase: 1; 5 | $Camel_Snake_Case: 1; 6 | $SCREAMING_SNAKE_CASE: 1; 7 | $_with-leading-underscore: 1; 8 | 9 | $strictbem: 1; 10 | $strictbem__variable: 1; 11 | $strictbem__variable_modifier: 1; 12 | $strictbem_modifier__variable: 1; 13 | $hyphenatedbem--modifier: 1; 14 | $hyphenatedbem__variable: 1; 15 | $hyphenatedbem__variable--modifier: 1; 16 | $hyphenatedbem--modifier__variable: 1; 17 | 18 | $_does_NOT-fitSTANDARD: 1; 19 | 20 | .class { 21 | width: $snake_case; 22 | } 23 | 24 | // Issue #901 - operators not recognized as separate tokens by gonzales-pe 25 | .content-main { 26 | padding: $mobile-site-gutter*1.5; 27 | } 28 | -------------------------------------------------------------------------------- /tests/sass/zero-unit.sass: -------------------------------------------------------------------------------- 1 | .baz 2 | border-right-width: 0px 3 | 4 | 5 | .foo 6 | margin: 0px 7 | padding: 0 8 | 9 | 10 | .bar 11 | padding: 5px 0 0px 12 | 13 | 14 | $foo: 0px 15 | $bar: '0px' 16 | 17 | .foo 18 | @if $bar == 0 19 | content: 'bar' 20 | 21 | 22 | @if $foo == '0px' 23 | content: 'foo' 24 | -------------------------------------------------------------------------------- /tests/sass/zero-unit.scss: -------------------------------------------------------------------------------- 1 | .baz { 2 | border-right-width: 0px; 3 | } 4 | 5 | .foo { 6 | margin: 0px; 7 | padding: 0; 8 | } 9 | 10 | .bar { 11 | padding: 5px 0 0px; 12 | } 13 | 14 | $foo: 0px; 15 | $bar: '0px'; 16 | 17 | .foo { 18 | @if $bar == 0 { 19 | content: 'bar'; 20 | } 21 | 22 | @if $foo == '0px' { 23 | content: 'foo'; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/testFile.txt: -------------------------------------------------------------------------------- 1 | This is a test file that test's the loadConfigFile helper function. -------------------------------------------------------------------------------- /tests/yml/.blank.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sasstools/sass-lint/52ccf2e1fa3e4d17d9f8f7bd748f7caf20830f30/tests/yml/.blank.yml -------------------------------------------------------------------------------- /tests/yml/.error-output.yml: -------------------------------------------------------------------------------- 1 | options: 2 | formatter: stylish 3 | cache-config: false 4 | merge-default-rules: false 5 | files: 6 | include: '**/*.s+(a|c)ss' 7 | rules: 8 | no-ids: 2 9 | no-color-literals: 1 10 | -------------------------------------------------------------------------------- /tests/yml/.extend-a1.yml: -------------------------------------------------------------------------------- 1 | options: 2 | config-file: extend/.extend-c.yml 3 | rules: 4 | no-ids: 2 5 | -------------------------------------------------------------------------------- /tests/yml/.extend-a2.yml: -------------------------------------------------------------------------------- 1 | options: 2 | config-file: extend/.extend-b.yml 3 | rules: 4 | no-ids: 2 5 | -------------------------------------------------------------------------------- /tests/yml/.ignore-file.yml: -------------------------------------------------------------------------------- 1 | options: 2 | formatter: stylish 3 | cache-config: false 4 | merge-default-rules: false 5 | files: 6 | include: '**/*.s+(a|c)ss' 7 | ignore: '**/cli.scss' 8 | rules: 9 | no-color-literals: 1 10 | -------------------------------------------------------------------------------- /tests/yml/.indentation-error.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | indentation: 2 3 | -------------------------------------------------------------------------------- /tests/yml/.indentation-warn.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | indentation: 1 3 | -------------------------------------------------------------------------------- /tests/yml/.max-0-warnings.yml: -------------------------------------------------------------------------------- 1 | options: 2 | max-warnings: 0 3 | -------------------------------------------------------------------------------- /tests/yml/.max-10-warnings.yml: -------------------------------------------------------------------------------- 1 | options: 2 | max-warnings: 10 3 | -------------------------------------------------------------------------------- /tests/yml/.max-100-warnings.yml: -------------------------------------------------------------------------------- 1 | options: 2 | max-warnings: 100 3 | -------------------------------------------------------------------------------- /tests/yml/.sass-lint.yml/.sass-lint.yml: -------------------------------------------------------------------------------- 1 | options: 2 | formatter: json 3 | cache-config: false 4 | merge-default-rules: false 5 | files: 6 | include: '**/*.s+(a|c)ss' 7 | rules: 8 | no-color-keywords: 1 9 | -------------------------------------------------------------------------------- /tests/yml/.sasslintrc/.sasslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "options": { 3 | "formatter": "json", 4 | "cache-config": false, 5 | "merge-default-rules": false 6 | }, 7 | "files": { 8 | "include": "**/*.s+(a|c)ss" 9 | }, 10 | "rules": { 11 | "no-color-keywords": 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/yml/extend/.extend-b.yml: -------------------------------------------------------------------------------- 1 | options: 2 | config-file: .extend-c.yml 3 | rules: 4 | no-ids: 0 5 | no-mergeable-selectors: 2 6 | -------------------------------------------------------------------------------- /tests/yml/extend/.extend-c.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | no-ids: 1 3 | no-important: 2 4 | -------------------------------------------------------------------------------- /tests/yml/extend/find-file-test/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sasstools/sass-lint/52ccf2e1fa3e4d17d9f8f7bd748f7caf20830f30/tests/yml/extend/find-file-test/.gitignore --------------------------------------------------------------------------------