diff --git a/.dockerignore b/.dockerignore index 284b069..7d55e2b 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,4 @@ +.eslintcache .git dist node_modules diff --git a/.eslintrc.yml b/.eslintrc.yml deleted file mode 100644 index b85eb56..0000000 --- a/.eslintrc.yml +++ /dev/null @@ -1,6 +0,0 @@ -extends: seegno - -rules: - complexity: [2, 12] - id-length: 0 - no-sync: 0 diff --git a/.gitignore b/.gitignore index 3c3629e..7186998 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ +.eslintcache node_modules diff --git a/.jscsrc b/.jscsrc deleted file mode 100644 index 872495e..0000000 --- a/.jscsrc +++ /dev/null @@ -1,4 +0,0 @@ -plugins: - - jscs-config-seegno - -preset: seegno diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..d5ed481 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,34 @@ +/** + * Module dependencies. + */ + +import { defineConfig } from 'eslint/config'; +import uphold, { mocha as upholdMochaConfig } from 'eslint-config-uphold'; + +/** + * `ESLint` configuration. + */ + +export default defineConfig([ + uphold, + { ignores: ['dist/**'] }, + { + files: ['**/*.js'], + name: 'uk-modulus-checking/config', + rules: { + // Weight table columns are named after single letters in the VocaLink specification. + 'id-length': 'off', + // Data sets are read from disk once, on instantiation. + 'n/no-sync': 'off' + } + }, + { + extends: [upholdMochaConfig], + files: ['test/**/*.js'], + name: 'uk-modulus-checking/tests', + rules: { + // Test cases are generated from the VocaLink account number fixtures. + 'mocha/no-setup-in-describe': 'off' + } + } +]); diff --git a/package.json b/package.json index 901793c..52adedf 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ }, "scripts": { "changelog": "github_changelog_generator --no-issues --header-label='# Changelog'", - "lint": "eslint src test && jscs src test", + "lint": "eslint --cache src test", "prepublish": "npm run transpile", "testdocker": "docker-compose run --rm sut", "test": "mocha $npm_package_options_mocha", @@ -28,18 +28,16 @@ }, "devDependencies": { "babel-cli": "^6.4.0", - "babel-eslint": "^4.1.6", "babel-plugin-add-module-exports": "^0.1.2", "babel-plugin-static-fs": "^1.2.0", "babel-preset-es2015": "6.5.0", "babel-register": "^6.3.13", - "eslint": "^1.10.3", - "eslint-config-seegno": "2.0.0", - "eslint-plugin-babel": "^3.0.0", - "jscs": "^2.7.0", - "jscs-config-seegno": "^1.0.0", + "eslint": "~10.6.0", + "eslint-config-uphold": "^7.0.0", + "eslint-plugin-mocha": "^11.3.0", "mocha": "^2.3.4", "pre-commit": "^1.1.2", + "prettier": "^3.9.4", "should": "^8.0.0" }, "pre-commit": [ diff --git a/src/constants.js b/src/constants.js index f05556d..61729a0 100644 --- a/src/constants.js +++ b/src/constants.js @@ -1,5 +1,8 @@ +/** + * Exports. + */ -/* jscs:disable validateOrderInObjectKeys */ +/* eslint-disable sort-keys-fix/sort-keys-fix */ export const positions = { u: 0, v: 1, @@ -16,4 +19,4 @@ export const positions = { g: 12, h: 13 }; -/* jscs:enable validateOrderInObjectKeys */ +/* eslint-enable sort-keys-fix/sort-keys-fix */ diff --git a/src/index.js b/src/index.js index 8ecc904..0dd3cbd 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,3 @@ - /** * Module dependencies. */ @@ -12,7 +11,6 @@ import path from 'path'; */ export default class UkModulusChecking { - /** * Constructor. */ @@ -48,12 +46,27 @@ export default class UkModulusChecking { if (check.exception === 10) { const ab = number.charAt(positions.a) + number.charAt(positions.b); - if (ab === '09' || ab === '99' && this.pickPosition(number, 'b') === 9) { + if (ab === '09' || (ab === '99' && this.pickPosition(number, 'b') === 9)) { return [0, 0, 0, 0, 0, 0, 0, 0, check.c, check.d, check.e, check.f, check.g, check.h]; } } - return [check.u, check.v, check.w, check.x, check.y, check.z, check.a, check.b, check.c, check.d, check.e, check.f, check.g, check.h]; + return [ + check.u, + check.v, + check.w, + check.x, + check.y, + check.z, + check.a, + check.b, + check.c, + check.d, + check.e, + check.f, + check.g, + check.h + ]; } /** @@ -61,7 +74,7 @@ export default class UkModulusChecking { */ getNumber(check, number) { - let sortCode = this.sortCode; + let { sortCode } = this; number = number || this.accountNumber; @@ -123,7 +136,12 @@ export default class UkModulusChecking { return true; } - if (check.exception === 6 && this.pickPosition(number, 'a') >= 4 && this.pickPosition(number, 'a') <= 8 && this.pickPosition(number, 'g') === this.pickPosition(number, 'h')) { + if ( + check.exception === 6 && + this.pickPosition(number, 'a') >= 4 && + this.pickPosition(number, 'a') <= 8 && + this.pickPosition(number, 'g') === this.pickPosition(number, 'h') + ) { return true; } @@ -199,46 +217,46 @@ export default class UkModulusChecking { * Is valid. */ - isValid() { - if (this.accountNumber.length < 6 || this.accountNumber.length > 10 || this.sortCode.length !== 6) { - return false; - } + isValid() { + if (this.accountNumber.length < 6 || this.accountNumber.length > 10 || this.sortCode.length !== 6) { + return false; + } - const checks = this.getSortCodeChecks(); + const checks = this.getSortCodeChecks(); - // If no range is found that contains the sorting code, there is no modulus check that can be performed. - // The sorting code and account number should be presumed valid unless other evidence implies otherwise. - if (checks.length === 0) { - return true; - } + // If no range is found that contains the sorting code, there is no modulus check that can be performed. + // The sorting code and account number should be presumed valid unless other evidence implies otherwise. + if (checks.length === 0) { + return true; + } - const firstCheck = checks[0]; + const [firstCheck] = checks; - if (this.isCheckValid(firstCheck)) { - if (checks.length === 1 || [2, 9, 10, 11, 12, 13, 14].indexOf(firstCheck.exception) !== -1) { - return true; - } + if (this.isCheckValid(firstCheck)) { + if (checks.length === 1 || [2, 9, 10, 11, 12, 13, 14].indexOf(firstCheck.exception) !== -1) { + return true; + } - // Verify second check. - return this.isCheckValid(checks[1]); - } + // Verify second check. + return this.isCheckValid(checks[1]); + } - if (firstCheck.exception === 14) { - if ([0, 1, 9].indexOf(parseInt(this.accountNumber.charAt(7), 10)) === -1) { - return false; - } + if (firstCheck.exception === 14) { + if ([0, 1, 9].indexOf(parseInt(this.accountNumber.charAt(7), 10)) === -1) { + return false; + } - // If the 8th digit is 0, 1 or 9, then remove the digit from the account number and insert a 0 as the 1st digit for check purposes only - return this.isCheckValid(checks[0], `0${this.accountNumber.substring(7, 0)}`); - } + // If the 8th digit is 0, 1 or 9, then remove the digit from the account number and insert a 0 as the 1st digit for check purposes only. + return this.isCheckValid(checks[0], `0${this.accountNumber.substring(7, 0)}`); + } - if (checks.length === 1 || [2, 9, 10, 11, 12, 13, 14].indexOf(firstCheck.exception) === -1) { - return false; - } + if (checks.length === 1 || [2, 9, 10, 11, 12, 13, 14].indexOf(firstCheck.exception) === -1) { + return false; + } - // Verify second check. - return this.isCheckValid(checks[1]); - } + // Verify second check. + return this.isCheckValid(checks[1]); + } /** * Load scsubtab file. @@ -248,7 +266,7 @@ export default class UkModulusChecking { const content = fs.readFileSync(path.join(__dirname, 'data', 'scsubtab.txt'), 'utf8'); const scsubtab = []; - content.split('\r\n').forEach((line) => { + content.split('\r\n').forEach(line => { const data = line.split(/\s+/); scsubtab.push({ @@ -268,10 +286,10 @@ export default class UkModulusChecking { const content = fs.readFileSync(path.join(__dirname, 'data', 'valacdos-v900.txt'), 'utf8'); const valacdos = []; - content.split('\r\n').forEach((line) => { + content.split('\r\n').forEach(line => { const data = line.split(/\s+/); - /* jscs:disable validateOrderInObjectKeys */ + /* eslint-disable sort-keys-fix/sort-keys-fix */ valacdos.push({ start: parseInt(data[0], 10), end: parseInt(data[1], 10), @@ -292,7 +310,7 @@ export default class UkModulusChecking { h: parseInt(data[16], 10), exception: parseInt(data[17], 10) || null }); - /* jscs:enable validateOrderInObjectKeys */ + /* eslint-enable sort-keys-fix/sort-keys-fix */ }); return valacdos; @@ -302,9 +320,9 @@ export default class UkModulusChecking { * Pick position in number. */ - pickPosition(number, position) { - return parseInt(number.charAt(positions[position]), 10); - } + pickPosition(number, position) { + return parseInt(number.charAt(positions[position]), 10); + } /** * Sanitize. diff --git a/test/index_test.js b/test/index_test.js index 25cc4f1..ee646c0 100644 --- a/test/index_test.js +++ b/test/index_test.js @@ -1,4 +1,3 @@ - /** * Module dependencies. */ @@ -50,29 +49,33 @@ const accounts = { * Test `UkModulusChecking`. */ -describe('UkModulusChecking', () => { - describe('isValid()', () => { - it('should return false if account number length is less than 6', () => { +describe('UkModulusChecking', function () { + describe('isValid()', function () { + it('should return false if account number length is less than 6', function () { new UkModulusChecking({ accountNumber: '12345', sortCode: '123456' }).isValid().should.be.false(); }); - it('should return false if account number length is greater than 10', () => { + it('should return false if account number length is greater than 10', function () { new UkModulusChecking({ accountNumber: '12345678901', sortCode: '123456' }).isValid().should.be.false(); }); - it('should return false if sort code length is not 6', () => { + it('should return false if sort code length is not 6', function () { new UkModulusChecking({ accountNumber: '12345789', sortCode: '12345' }).isValid().should.be.false(); }); - accounts.invalid.forEach((account) => { - it(`should return false if sort code is ${account.sortCode} and account number is ${account.accountNumber}`, () => { - new UkModulusChecking({ accountNumber: account.accountNumber, sortCode: account.sortCode }).isValid().should.be.false(); + accounts.invalid.forEach(account => { + it(`should return false if sort code is ${account.sortCode} and account number is ${account.accountNumber}`, function () { + new UkModulusChecking({ accountNumber: account.accountNumber, sortCode: account.sortCode }) + .isValid() + .should.be.false(); }); }); - accounts.valid.forEach((account) => { - it(`should return true if sort code is ${account.sortCode} and account number is ${account.accountNumber}`, () => { - new UkModulusChecking({ accountNumber: account.accountNumber, sortCode: account.sortCode }).isValid().should.be.true(); + accounts.valid.forEach(account => { + it(`should return true if sort code is ${account.sortCode} and account number is ${account.accountNumber}`, function () { + new UkModulusChecking({ accountNumber: account.accountNumber, sortCode: account.sortCode }) + .isValid() + .should.be.true(); }); }); });