diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..85da40e --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "loose": "all" +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/.jscsrc b/.jscsrc new file mode 100644 index 0000000..7b52ae6 --- /dev/null +++ b/.jscsrc @@ -0,0 +1,74 @@ +additionalRules: [ ./dist/rules/*.js ] +disallowDanglingUnderscores: true +disallowEmptyBlocks: true +disallowGeneratorsInDescribeFunctions: true +disallowKeywords: [ with ] +disallowKeywordsInComments: true +disallowKeywordsOnNewLine: [ catch, else, while ] +disallowMixedSpacesAndTabs: true +disallowMultipleLineBreaks: true +disallowMultipleLineStrings: true +disallowMultipleSpaces: true +disallowMultipleVarDecl: strict +disallowNewlineBeforeBlockStatements: true +disallowNodeTypes: [ LabeledStatement ] +disallowOnlyFilterInTestFunctions: true +disallowOperatorBeforeLineBreak: true +disallowPaddingNewlinesInBlocks: true +disallowQuotedKeysInObjects: true +disallowSpaceAfterObjectKeys: true +disallowSpaceAfterPrefixUnaryOperators: true +disallowSpaceBeforeComma: true +disallowSpaceBeforePostfixUnaryOperators: true +disallowSpaceBeforeSemicolon: true +disallowSpacesInCallExpression: true +disallowSpacesInFunctionDeclaration: { beforeOpeningRoundBrace: true } +disallowSpacesInsideArrayBrackets: true +disallowSpacesInsideParentheses: true +disallowSpacesInsideParenthesizedExpression: true +disallowTrailingComma: true +disallowTrailingWhitespace: true +disallowYodaConditions: true +esnext: true +excludeFiles: [ .git, dist, node_modules ] +requireBlocksOnNewline: 1 +requireCamelCaseOrUpperCaseIdentifiers: true +requireCapitalizedComments: { allExcept: [eslint] } +requireCapitalizedConstructors: true +requireCommaBeforeLineBreak: true +requireCurlyBraces: true +requireDotNotation: true +requireLineBreakAfterVariableAssignment: true +requireLineFeedAtFileEnd: true +requireMatchingFunctionName: true +requirePaddingNewLineAfterVariableDeclaration: true +requirePaddingNewLinesAfterBlocks: { allExcept: ['inCallExpressions', 'inNewExpressions', 'inArrayExpressions', 'inProperties'] } +requirePaddingNewLinesAfterUseStrict: true +requirePaddingNewLinesBeforeExport: true +requirePaddingNewLinesBeforeLineComments: { allExcept: firstAfterCurly } +requirePaddingNewlinesBeforeKeywords: [ case, do, finally, for, function, if, return, switch, try, typeof, void, while, with ] +requireParenthesesAroundIIFE: true +requireSemicolons: true +requireShouldAssertionExecution: true +requireSpaceAfterBinaryOperators: true +requireSpaceAfterComma: true +requireSpaceAfterKeywords: [ case, catch, do, finally, for, if, return, switch, try, typeof, while, with ] +requireSpaceAfterLineComment: true +requireSpaceBeforeBinaryOperators: true +requireSpaceBeforeBlockStatements: true +requireSpaceBeforeKeywords: [ catch, else, while ] +requireSpaceBeforeObjectValues: true +requireSpaceBetweenArguments: true +requireSpacesInAnonymousFunctionExpression: { beforeOpeningCurlyBrace: true } +requireSpacesInConditionalExpression: true +requireSpacesInForStatement: true +requireSpacesInsideObjectBrackets: all +requireSpread: true +requireSqlTemplateInQueryFunction: true +requireTemplateStrings: true +safeContextKeyword: self +validateIndentation: 2 +validateLineBreaks: LF +validateOrderInObjectKeys: asc +validateParameterSeparator: ", " +validateQuoteMarks: "'" diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..e340b8b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,6 @@ +language: node_js + +node_js: + - node + +sudo: false diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..090be29 --- /dev/null +++ b/LICENSE @@ -0,0 +1 @@ +(c) Copyright 2015 Seegno, Inc. All rights reserved. diff --git a/README.md b/README.md index 9750687..c2e6340 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,34 @@ # jscs-config-seegno Seegno-flavored JSCS config. + +## Installation + +```sh +$ npm install jscs jscs-config-seegno --save-dev +``` + +## Usage + +Create an `.jscsrc` file with the following: + +```yaml +plugins: + - 'jscs-config-seegno' + +preset: seegno +``` + +Add the following `script` to your `package.json`: + +```json +scripts: { + "lint": "jscs ." +} +``` + +and run the linter with: + +```sh +$ npm run lint +``` diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 0000000..cc35cde --- /dev/null +++ b/dist/index.js @@ -0,0 +1,35 @@ +'use strict'; + +/** + * Module dependencies. + */ + +exports.__esModule = true; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _jscsLibCliConfig = require('jscs/lib/cli-config'); + +var _jscsLibCliConfig2 = _interopRequireDefault(_jscsLibCliConfig); + +var _path = require('path'); + +var _path2 = _interopRequireDefault(_path); + +/** + * Instances. + */ + +var dir = _path2['default'].join(__dirname, '..'); +var config = _jscsLibCliConfig2['default'].load('.jscsrc', dir); + +/** + * Export custom configuration. + */ + +function register(conf) { + conf.registerPreset('seegno', config); +} + +exports['default'] = register; +module.exports = exports['default']; \ No newline at end of file diff --git a/dist/rules/disallow-generators-in-describe-functions.js b/dist/rules/disallow-generators-in-describe-functions.js new file mode 100644 index 0000000..5a5e274 --- /dev/null +++ b/dist/rules/disallow-generators-in-describe-functions.js @@ -0,0 +1,46 @@ +'use strict'; + +/** + * Module dependencies. + */ + +exports.__esModule = true; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _assert = require('assert'); + +var _assert2 = _interopRequireDefault(_assert); + +/** + * Export `disallowGeneratorsInDescribeFunctions`. + */ + +var disallowGeneratorsInDescribeFunctions = function disallowGeneratorsInDescribeFunctions() {}; + +disallowGeneratorsInDescribeFunctions.prototype = { + check: function check(file, errors) { + file.iterateNodesByType('CallExpression', function (node) { + if (node.callee.name !== 'describe') { + return; + } + + node.arguments.filter(function (argument) { + return argument.type === 'FunctionExpression' && argument.generator === true; + }).forEach(function (argument) { + errors.add('Do not use generators in describe functions', argument.loc.start); + }); + }); + }, + + configure: function configure(disallowGeneratorsInDescribeFunctions) { + _assert2['default'](disallowGeneratorsInDescribeFunctions === true || disallowGeneratorsInDescribeFunctions === false, 'disallowGeneratorsInDescribeFunctions must be a boolean'); + }, + + getOptionName: function getOptionName() { + return 'disallowGeneratorsInDescribeFunctions'; + } +}; + +exports['default'] = disallowGeneratorsInDescribeFunctions; +module.exports = exports['default']; \ No newline at end of file diff --git a/dist/rules/disallow-only-filter-in-test-function.js b/dist/rules/disallow-only-filter-in-test-function.js new file mode 100644 index 0000000..066451a --- /dev/null +++ b/dist/rules/disallow-only-filter-in-test-function.js @@ -0,0 +1,42 @@ +'use strict'; + +/** + * Module dependencies. + */ + +exports.__esModule = true; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _assert = require('assert'); + +var _assert2 = _interopRequireDefault(_assert); + +/** + * Export `disallowOnlyFilterInTestFunctions`. + */ + +var disallowOnlyFilterInTestFunctions = function disallowOnlyFilterInTestFunctions() {}; + +disallowOnlyFilterInTestFunctions.prototype = { + check: function check(file, errors) { + file.iterateNodesByType('MemberExpression', function (node) { + if (node.property.name !== 'only' && (node.object.name !== 'describe' || node.object.name !== 'it')) { + return; + } + + errors.add('Do not use `.only` in `' + node.object.name + '` functions', node.property.loc.start); + }); + }, + + configure: function configure(disallowOnlyFilterInTestFunctions) { + _assert2['default'](disallowOnlyFilterInTestFunctions === true || disallowOnlyFilterInTestFunctions === false, 'disallowOnlyFilterInTestFunctions must be a boolean'); + }, + + getOptionName: function getOptionName() { + return 'disallowOnlyFilterInTestFunctions'; + } +}; + +exports['default'] = disallowOnlyFilterInTestFunctions; +module.exports = exports['default']; \ No newline at end of file diff --git a/dist/rules/require-should-assertion-execution.js b/dist/rules/require-should-assertion-execution.js new file mode 100644 index 0000000..93371b0 --- /dev/null +++ b/dist/rules/require-should-assertion-execution.js @@ -0,0 +1,73 @@ +'use strict'; + +/** + * Module dependencies. + */ + +exports.__esModule = true; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _assert = require('assert'); + +var _assert2 = _interopRequireDefault(_assert); + +var _should = require('should'); + +var _should2 = _interopRequireDefault(_should); + +/** + * Auxiliary constants. + */ + +var Assertion = _should2['default'].Assertion.prototype; +var assertions = Object.keys(Assertion); +var chains = Object.keys(Assertion).filter(function (key) { + return typeof Assertion[key] !== 'function'; +}); + +/** + * Export `requireShouldAssertionExecution`. + */ + +var requireShouldAssertionExecution = function requireShouldAssertionExecution() {}; + +requireShouldAssertionExecution.prototype = { + check: function check(file, errors) { + file.iterateNodesByType('Identifier', function (node) { + if (!node.parentNode || !node.parentNode.object || !node.parentNode.object.property) { + return; + } + + // Skip non-assertions. + if (assertions.indexOf(node.name) === -1) { + return; + } + + // Skip assertion terms that are used in another conditions. + if (chains.indexOf(node.parentNode.object.property.name) === -1) { + return; + } + + // Allow chaining. + if (chains.indexOf(node.name) !== -1 && chains.indexOf(node.parentNode.object.property.name) !== -1) { + return; + } + + if (node.parentNode.parentNode.type !== 'CallExpression') { + errors.add('You must invoke the assertion in `should.' + node.name + '`', node.loc.end); + } + }); + }, + + configure: function configure(requireShouldAssertionExecution) { + _assert2['default'](requireShouldAssertionExecution === true || requireShouldAssertionExecution === false, 'requireShouldAssertionExecution must be a boolean'); + }, + + getOptionName: function getOptionName() { + return 'requireShouldAssertionExecution'; + } +}; + +exports['default'] = requireShouldAssertionExecution; +module.exports = exports['default']; \ No newline at end of file diff --git a/dist/rules/require-sql-template-in-query-function.js b/dist/rules/require-sql-template-in-query-function.js new file mode 100644 index 0000000..26b776d --- /dev/null +++ b/dist/rules/require-sql-template-in-query-function.js @@ -0,0 +1,48 @@ +'use strict'; + +/** + * Module dependencies. + */ + +exports.__esModule = true; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _assert = require('assert'); + +var _assert2 = _interopRequireDefault(_assert); + +/** + * Export `requireSqlTemplateInQueryFunction`. + */ + +var requireSqlTemplateInQueryFunction = function requireSqlTemplateInQueryFunction() {}; + +requireSqlTemplateInQueryFunction.prototype = { + check: function check(file, errors) { + file.iterateNodesByType('CallExpression', function (node) { + var property = node.callee.property; + + if (!property || property.name !== 'query') { + return; + } + + node.arguments.forEach(function (argument) { + if (argument.type !== 'TaggedTemplateExpression') { + errors.add('Use the `sql` tagged template literal for raw queries', argument.loc.start); + } + }); + }); + }, + + configure: function configure(requireSqlTemplate) { + _assert2['default'](requireSqlTemplate === true || requireSqlTemplate === false, 'requireSqlTemplate option requires sql tagged templates on raw queries'); + }, + + getOptionName: function getOptionName() { + return 'requireSqlTemplateInQueryFunction'; + } +}; + +exports['default'] = requireSqlTemplateInQueryFunction; +module.exports = exports['default']; \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..6830483 --- /dev/null +++ b/package.json @@ -0,0 +1,47 @@ +{ + "name": "jscs-config-seegno", + "version": "1.0.0", + "description": "Seegno-flavored JSCS config.", + "main": "dist/index.js", + "options": { + "mocha": "--compilers js:babel/register --recursive --require should test" + }, + "scripts": { + "build": "rm -rf dist/* && babel src/ --out-dir dist/", + "changelog": "github_changelog_generator --header-label='# Changelog'", + "lint": "jscs .", + "prepublish": "npm test && npm run build", + "test": "mocha $npm_package_options_mocha" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/seegno/jscs-config-seegno.git" + }, + "keywords": [ + "config", + "jscs", + "lint", + "shared" + ], + "author": "Seegno", + "license": "SEE LICENSE IN LICENSE", + "bugs": { + "url": "https://github.com/seegno/jscs-config-seegno/issues" + }, + "homepage": "https://github.com/seegno/jscs-config-seegno#readme", + "dependencies": { + "jscs": "^2.5.0" + }, + "devDependencies": { + "babel": "^5.8.23", + "mocha": "^2.3.3", + "should": "^7.1.0" + }, + "peerDependencies": { + "jscs": ">= 2.5", + "should": ">= 7.1" + }, + "engines": { + "node": ">= 4.0.0" + } +} diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..7a87abd --- /dev/null +++ b/src/index.js @@ -0,0 +1,25 @@ +'use strict'; + +/** + * Module dependencies. + */ + +import CliEngine from 'jscs/lib/cli-config'; +import path from 'path'; + +/** + * Instances. + */ + +const dir = path.join(__dirname, '..'); +const config = CliEngine.load('.jscsrc', dir); + +/** + * Export custom configuration. + */ + +function register(conf) { + conf.registerPreset('seegno', config); +} + +export default register; diff --git a/src/rules/disallow-generators-in-describe-functions.js b/src/rules/disallow-generators-in-describe-functions.js new file mode 100644 index 0000000..82fdc20 --- /dev/null +++ b/src/rules/disallow-generators-in-describe-functions.js @@ -0,0 +1,47 @@ +'use strict'; + +/** + * Module dependencies. + */ + +import assert from 'assert'; + +/** + * Export `disallowGeneratorsInDescribeFunctions`. + */ + +const disallowGeneratorsInDescribeFunctions = () => {}; + +disallowGeneratorsInDescribeFunctions.prototype = { + check: (file, errors) => { + file.iterateNodesByType('CallExpression', (node) => { + if (node.callee.name !== 'describe') { + return; + } + + node.arguments + .filter((argument) => { + return argument.type === 'FunctionExpression' && argument.generator === true; + }) + .forEach((argument) => { + errors.add( + 'Do not use generators in describe functions', + argument.loc.start + ); + }); + }); + }, + + configure: (disallowGeneratorsInDescribeFunctions) => { + assert( + disallowGeneratorsInDescribeFunctions === true || disallowGeneratorsInDescribeFunctions === false, + 'disallowGeneratorsInDescribeFunctions must be a boolean' + ); + }, + + getOptionName: () => { + return 'disallowGeneratorsInDescribeFunctions'; + } +}; + +export default disallowGeneratorsInDescribeFunctions; diff --git a/src/rules/disallow-only-filter-in-test-function.js b/src/rules/disallow-only-filter-in-test-function.js new file mode 100644 index 0000000..89c07ac --- /dev/null +++ b/src/rules/disallow-only-filter-in-test-function.js @@ -0,0 +1,38 @@ +'use strict'; + +/** + * Module dependencies. + */ + +import assert from 'assert'; + +/** + * Export `disallowOnlyFilterInTestFunctions`. + */ + +const disallowOnlyFilterInTestFunctions = () => {}; + +disallowOnlyFilterInTestFunctions.prototype = { + check: (file, errors) => { + file.iterateNodesByType('MemberExpression', (node) => { + if (node.property.name !== 'only' && (node.object.name !== 'describe' || node.object.name !== 'it')) { + return; + } + + errors.add(`Do not use \`.only\` in \`${node.object.name}\` functions`, node.property.loc.start); + }); + }, + + configure: (disallowOnlyFilterInTestFunctions) => { + assert( + disallowOnlyFilterInTestFunctions === true || disallowOnlyFilterInTestFunctions === false, + 'disallowOnlyFilterInTestFunctions must be a boolean' + ); + }, + + getOptionName: () => { + return 'disallowOnlyFilterInTestFunctions'; + } +}; + +export default disallowOnlyFilterInTestFunctions; diff --git a/src/rules/require-should-assertion-execution.js b/src/rules/require-should-assertion-execution.js new file mode 100644 index 0000000..b83e20f --- /dev/null +++ b/src/rules/require-should-assertion-execution.js @@ -0,0 +1,64 @@ +'use strict'; + +/** + * Module dependencies. + */ + +import assert from 'assert'; +import should from 'should'; + +/** + * Auxiliary constants. + */ + +const Assertion = should.Assertion.prototype; +const assertions = Object.keys(Assertion); +const chains = Object.keys(Assertion).filter(key => typeof Assertion[key] !== 'function'); + +/** + * Export `requireShouldAssertionExecution`. + */ + +const requireShouldAssertionExecution = () => {}; + +requireShouldAssertionExecution.prototype = { + check: (file, errors) => { + file.iterateNodesByType('Identifier', (node) => { + if (!node.parentNode || !node.parentNode.object || !node.parentNode.object.property) { + return; + } + + // Skip non-assertions. + if (assertions.indexOf(node.name) === -1) { + return; + } + + // Skip assertion terms that are used in another conditions. + if (chains.indexOf(node.parentNode.object.property.name) === -1) { + return; + } + + // Allow chaining. + if (chains.indexOf(node.name) !== -1 && chains.indexOf(node.parentNode.object.property.name) !== -1) { + return; + } + + if (node.parentNode.parentNode.type !== 'CallExpression') { + errors.add(`You must invoke the assertion in \`should.${node.name}\``, node.loc.end); + } + }); + }, + + configure: (requireShouldAssertionExecution) => { + assert( + requireShouldAssertionExecution === true || requireShouldAssertionExecution === false, + 'requireShouldAssertionExecution must be a boolean' + ); + }, + + getOptionName: () => { + return 'requireShouldAssertionExecution'; + } +}; + +export default requireShouldAssertionExecution; diff --git a/src/rules/require-sql-template-in-query-function.js b/src/rules/require-sql-template-in-query-function.js new file mode 100644 index 0000000..681dfb7 --- /dev/null +++ b/src/rules/require-sql-template-in-query-function.js @@ -0,0 +1,47 @@ +'use strict'; + +/** + * Module dependencies. + */ + +import assert from 'assert'; + +/** + * Export `requireSqlTemplateInQueryFunction`. + */ + +const requireSqlTemplateInQueryFunction = () => {}; + +requireSqlTemplateInQueryFunction.prototype = { + check: (file, errors) => { + file.iterateNodesByType('CallExpression', (node) => { + let property = node.callee.property; + + if (!property || property.name !== 'query') { + return; + } + + node.arguments.forEach((argument) => { + if (argument.type !== 'TaggedTemplateExpression') { + errors.add( + 'Use the `sql` tagged template literal for raw queries', + argument.loc.start + ); + } + }); + }); + }, + + configure: (requireSqlTemplate) => { + assert( + requireSqlTemplate === true || requireSqlTemplate === false, + 'requireSqlTemplate option requires sql tagged templates on raw queries' + ); + }, + + getOptionName: () => { + return 'requireSqlTemplateInQueryFunction'; + } +}; + +export default requireSqlTemplateInQueryFunction; diff --git a/test/index.js b/test/index.js new file mode 100644 index 0000000..0e50f3a --- /dev/null +++ b/test/index.js @@ -0,0 +1,49 @@ +'use strict'; + +/** + * Module dependencies. + */ + +import Checker from 'jscs'; +import path from 'path'; + +/** + * Tests for `jscs-config-seegno`. + */ + +describe('jscs-config-seegno', () => { + let checker; + + beforeEach(() => { + checker = new Checker(); + checker.configure({ plugins: [path.join(__dirname, '..', 'src')] }); + }); + + it('should load a valid config file', () => { + const preset = checker.getConfiguration().getRegisteredPresets().seegno; + + preset.should.be.an.Object().and.should.not.be.empty(); + preset.should.containEql(['additionalRules', 'esnext', 'excludeFiles']); + }); + + it('should define the proper environment', () => { + const preset = checker.getConfiguration().getRegisteredPresets().seegno; + + preset.esnext.should.be.true(); + preset.excludeFiles.should.be.an.Array().and.should.not.be.empty(); + preset.excludeFiles.should.have.length(3); + preset.excludeFiles.should.eql(['.git', 'dist', 'node_modules']); + }); + + it('should include the additional custom rules', () => { + const preset = checker.getConfiguration().getRegisteredPresets().seegno; + + preset.additionalRules.should.be.an.Array().and.should.not.be.empty(); + preset.additionalRules.should.have.length(1); + preset.additionalRules.should.eql(['./dist/rules/*.js']); + preset.disallowGeneratorsInDescribeFunctions.should.be.true(); + preset.disallowOnlyFilterInTestFunctions.should.be.true(); + preset.requireShouldAssertionExecution.should.be.true(); + preset.requireSqlTemplateInQueryFunction.should.be.true(); + }); +}); diff --git a/test/rules/disallow-generators-in-describe-functions_test.js b/test/rules/disallow-generators-in-describe-functions_test.js new file mode 100644 index 0000000..9c3613e --- /dev/null +++ b/test/rules/disallow-generators-in-describe-functions_test.js @@ -0,0 +1,39 @@ +'use strict'; + +/** + * Module dependencies. + */ + +import Checker from 'jscs'; +import Rule from '../../src/rules/disallow-generators-in-describe-functions'; + +/** + * Tests for `disallow-generators-in-describe-functions`. + */ + +describe('disallow-generators-in-describe-functions rule', function() { + let checker; + + beforeEach(() => { + checker = new Checker(); + checker.configure({ + additionalRules: [new Rule()], + disallowGeneratorsInDescribeFunctions: true + }); + }); + + it('should return an error if the source contains `describe("foobar", function* () {});` statements', () => { + const results = checker.checkString('describe("foobar", function* () {});'); + const errors = results.getErrorList(); + + errors.should.have.length(1); + errors[0].rule.should.equal('disallowGeneratorsInDescribeFunctions'); + }); + + it('should allow regular `describe("foobar", function() {});` statements', () => { + const results = checker.checkString('describe("foobar", function() {});'); + const errors = results.getErrorList(); + + errors.should.have.length(0); + }); +}); diff --git a/test/rules/disallow-only-filter-in-test-function_test.js b/test/rules/disallow-only-filter-in-test-function_test.js new file mode 100644 index 0000000..b35a34e --- /dev/null +++ b/test/rules/disallow-only-filter-in-test-function_test.js @@ -0,0 +1,54 @@ +'use strict'; + +/** + * Module dependencies. + */ + +import Checker from 'jscs'; +import Rule from '../../src/rules/disallow-only-filter-in-test-function'; + +/** + * Tests for `disallow-only-filter-in-test-function`. + */ + +describe('disallow-only-filter-in-test-function rule', () => { + let checker; + + beforeEach(() => { + checker = new Checker(); + checker.configure({ + additionalRules: [new Rule()], + disallowOnlyFilterInTestFunctions: true + }); + }); + + it('should return an error if the source contains `describe.only()` statements', () => { + const results = checker.checkString('describe.only("foobar")'); + const errors = results.getErrorList(); + + errors.should.have.length(1); + errors[0].rule.should.equal('disallowOnlyFilterInTestFunctions'); + }); + + it('should return an error if the source contains `test.only()` statements', () => { + const results = checker.checkString('test.only("foobar")'); + const errors = results.getErrorList(); + + errors.should.have.length(1); + errors[0].rule.should.equal('disallowOnlyFilterInTestFunctions'); + }); + + it('should allow regular `describe()` statements', () => { + const results = checker.checkString('describe("foobar")'); + const errors = results.getErrorList(); + + errors.should.have.length(0); + }); + + it('should allow regular `test()` statements', () => { + const results = checker.checkString('test("something")'); + const errors = results.getErrorList(); + + errors.should.have.length(0); + }); +}); diff --git a/test/rules/require-should-assertion-execution_test.js b/test/rules/require-should-assertion-execution_test.js new file mode 100644 index 0000000..0542ab1 --- /dev/null +++ b/test/rules/require-should-assertion-execution_test.js @@ -0,0 +1,39 @@ +'use strict'; + +/** + * Module dependencies. + */ + +import Checker from 'jscs'; +import Rule from '../../src/rules/require-should-assertion-execution'; + +/** + * Tests for `require-should-assertion-execution`. + */ + +describe('require-should-assertion-execution rule', () => { + let checker; + + beforeEach(() => { + checker = new Checker(); + checker.configure({ + additionalRules: [new Rule()], + requireShouldAssertionExecution: true + }); + }); + + it('should return an error if the source contains `foo.should.be.ok;` type of statements', () => { + const results = checker.checkString('foo.should.be.ok;'); + const errors = results.getErrorList(); + + errors.should.have.length(1); + errors[0].rule.should.equal('requireShouldAssertionExecution'); + }); + + it('should allow `foo.should.be.ok()` statements', () => { + const results = checker.checkString('foo.should.be.ok()'); + const errors = results.getErrorList(); + + errors.should.have.length(0); + }); +}); diff --git a/test/rules/require-sql-template-in-query-function_test.js b/test/rules/require-sql-template-in-query-function_test.js new file mode 100644 index 0000000..c2bf125 --- /dev/null +++ b/test/rules/require-sql-template-in-query-function_test.js @@ -0,0 +1,39 @@ +'use strict'; + +/** + * Module dependencies. + */ + +import Checker from 'jscs'; +import Rule from '../../src/rules/require-sql-template-in-query-function'; + +/** + * Tests for `require-sql-template-in-query-function`. + */ + +describe('require-sql-template-in-query-function rule', () => { + let checker; + + beforeEach(() => { + checker = new Checker(); + checker.configure({ + additionalRules: [new Rule()], + requireSqlTemplateInQueryFunction: true + }); + }); + + it('should return an error if the source contains `query("foobar")` statements', () => { + const results = checker.checkString('foo.query("SELECT bar FROM foobar;");'); + const errors = results.getErrorList(); + + errors.should.have.length(1); + errors[0].rule.should.equal('requireSqlTemplateInQueryFunction'); + }); + + it('should allow template `query(sql`foobar`)` statements', () => { + const results = checker.checkString('foo.query(sql`SELECT bar FROM foobar;`)'); + const errors = results.getErrorList(); + + errors.should.have.length(0); + }); +});