Skip to content
This repository has been archived by the owner on Aug 7, 2023. It is now read-only.

Commit

Permalink
Move rule related logic to a class
Browse files Browse the repository at this point in the history
Pull all the logic related to storing the list of known rules and
accessing it out into a class of its own.
  • Loading branch information
Arcanemagus committed Jan 16, 2018
1 parent 37553d9 commit afc5af5
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 111 deletions.
48 changes: 0 additions & 48 deletions spec/helpers-spec.js

This file was deleted.

54 changes: 54 additions & 0 deletions spec/rules-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
'use babel'

import Rules from '../src/rules'

describe('The Rules class', () => {
describe('updateRules', () => {
const ruleArray = [
['foo', { meta: { fixable: true } }],
['bar', { meta: {} }]
]

it('adds new rules', () => {
const rules = new Rules()
expect(rules.getRules()).toEqual(new Map())
rules.updateRules(ruleArray)
expect(rules.getRules()).toEqual(new Map(ruleArray))
})

it('removes old rules', () => {
const rules = new Rules()
rules.updateRules(ruleArray)
expect(rules.getRules()).toEqual(new Map(ruleArray))
rules.updateRules([])
expect(rules.getRules()).toEqual(new Map())
})

it('updates the fixableRules list', () => {
const rules = new Rules()
expect(rules.getFixableRules()).toEqual([])
rules.updateRules(ruleArray)
expect(rules.getFixableRules()).toEqual(['foo'])
})
})

describe('getRuleUrl', () => {
it('works with rules that define their own URL', () => {
const rules = new Rules()
rules.updateRules([['foo', { meta: { docs: { url: 'bar' } } }]])
expect(rules.getRuleUrl('foo')).toBe('bar')
})

it('works with rules defined in eslint-rule-documentation', () => {
const rules = new Rules()
const url = 'https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-duplicates.md'
expect(rules.getRuleUrl('import/no-duplicates')).toBe(url)
})

it('gives a fallback URL on how to add a rule URL', () => {
const rules = new Rules()
const url = 'https://github.com/jfmengels/eslint-rule-documentation/blob/master/contributing.md'
expect(rules.getRuleUrl('foo/bar')).toBe(url)
})
})
})
66 changes: 4 additions & 62 deletions src/helpers.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
'use babel'

import { join } from 'path'
import ruleURI from 'eslint-rule-documentation'
import { generateRange } from 'atom-linter'
import cryptoRandomString from 'crypto-random-string'

// eslint-disable-next-line import/no-extraneous-dependencies, import/extensions
import { Range } from 'atom'
import Rules from './rules'

const lintRules = new Map()
const fixableRules = new Set()
export const rules = new Rules()

/**
* Start the worker process if it hasn't already been started
Expand Down Expand Up @@ -66,10 +64,6 @@ export async function sendJob(worker, config) {
})
}

export function getFixableRules() {
return Array.from(fixableRules.values())
}

function validatePoint(textBuffer, line, col) {
// Clip the given point to a valid one, and check if it equals the original
if (!textBuffer.clipPosition([line, col]).isEqual([line, col])) {
Expand Down Expand Up @@ -222,25 +216,6 @@ const generateInvalidTrace = async ({
}
}

/**
* Get the URL of the documentation for a rule, either from the rule's own
* metadata, from eslint-rule-documentation's known rules, or the fallback URL
* on how to add it to eslint-rule-documentation.
* @param {String} ruleId The rule ID to get the documentation URL for
* @return {String} URL of the rule documentation
*/
export function getRuleUrl(ruleId) {
const props = lintRules.get(ruleId)
if (props && props.meta && props.meta.docs && props.meta.docs.url) {
// The rule has a documentation URL specified in its metadata
return props.meta.docs.url
}

// The rule didn't specify a URL in its metadata, or was not currently known
// somehow. Attempt to determine a URL using eslint-rule-documentation.
return ruleURI(ruleId).url
}

/**
* Given a raw response from ESLint, this processes the messages into a format
* compatible with the Linter API.
Expand Down Expand Up @@ -299,7 +274,7 @@ export async function processESLintMessages(messages, textEditor, showRule, work
}

if (ruleId) {
ret.url = getRuleUrl(ruleId)
ret.url = rules.getRuleUrl(ruleId)
}

let range
Expand Down Expand Up @@ -339,39 +314,6 @@ export async function processESLintMessages(messages, textEditor, showRule, work
}))
}

/**
* Update the list of fixable rules
*/
function updateFixableRules() {
fixableRules.clear()
lintRules.forEach((props, rule) => {
if (
Object.prototype.hasOwnProperty.call(props, 'meta') &&
Object.prototype.hasOwnProperty.call(props.meta, 'fixable')
) {
fixableRules.add(rule)
}
})
}

/**
* Process the updated rules into the local Map and call further update functions
* @param {Array} updatedRules Array of Arrays of the rule and properties
*/
export function updateRules(updatedRules) {
lintRules.clear()
updatedRules.forEach(([rule, props]) => lintRules.set(rule, props))
updateFixableRules()
}

/**
* Return the known list of rules.
* @return {Map} The currently known rules
*/
export function getRules() {
return lintRules
}

/**
* Processes the response from the lint job
* @param {Object} response The raw response from the job
Expand All @@ -382,7 +324,7 @@ export function getRules() {
*/
export async function processJobResponse(response, textEditor, showRule, worker) {
if (Object.prototype.hasOwnProperty.call(response, 'updatedRules')) {
updateRules(response.updatedRules)
rules.updateRules(response.updatedRules)
}
return processESLintMessages(response.messages, textEditor, showRule, worker)
}
2 changes: 1 addition & 1 deletion src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ module.exports = {
}
if (textEditor.isModified() && ignoreFixableRulesWhileTyping) {
// Note that this list will only contain rules after the first lint job
rules = idsToIgnoredRules(helpers.getFixableRules())
rules = idsToIgnoredRules(helpers.rules.getFixableRules())
}

if (!this.worker) {
Expand Down
66 changes: 66 additions & 0 deletions src/rules.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import ruleURI from 'eslint-rule-documentation'

/**
* Stores a list of rules from ESLint
*/
export default class Rules {
/**
* Instantiates a Rules object, optionally with an existing list of rules
* @param {Array} newRules Array of Arrays of the rule and properties
*/
constructor(newRules) {
this.rules = new Map()
if (newRules) {
this.updateRules(newRules)
}
}

/**
* Process the updated rules into the local Map and call further update functions
* @param {Array} updatedRules Array of Arrays of the rule and properties
*/
updateRules(updatedRules) {
this.rules.clear()
updatedRules.forEach(([rule, props]) => this.rules.set(rule, props))
}

/**
* [getFixableRules description]
* @return {Array} The ruleIds of the currently known fixable rules
*/
getFixableRules() {
return Array.from(this.rules).reduce((fixable, [rule, props]) => {
if (props.meta && props.meta.fixable) {
return [...fixable, rule]
}
return fixable
}, [])
}

/**
* Get the URL of the documentation for a rule, either from the rule's own
* metadata, from eslint-rule-documentation's known rules, or the fallback URL
* on how to add it to eslint-rule-documentation.
* @param {String} ruleId The rule ID to get the documentation URL for
* @return {String} URL of the rule documentation
*/
getRuleUrl(ruleId) {
const props = this.rules.get(ruleId)
if (props && props.meta && props.meta.docs && props.meta.docs.url) {
// The rule has a documentation URL specified in its metadata
return props.meta.docs.url
}

// The rule didn't specify a URL in its metadata, or was not currently known
// somehow. Attempt to determine a URL using eslint-rule-documentation.
return ruleURI(ruleId).url
}

/**
* Return the known rules.
* @return {Map} The currently known rules
*/
getRules() {
return new Map(this.rules)
}
}

0 comments on commit afc5af5

Please sign in to comment.