Skip to content

Commit

Permalink
Merge branch 'types-refactor'
Browse files Browse the repository at this point in the history
  • Loading branch information
rrd108 committed Sep 4, 2024
2 parents c6a651a + b8a1250 commit 892d576
Show file tree
Hide file tree
Showing 9 changed files with 589 additions and 552 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Options:
| `--apply` | Apply **only** specific rulesets or rules (comma-separated) | All rules | `--apply=vue-essential,magicNumbers` |
| `--ignore` | Ignore **only** specific rulesets or rules (comma-separated) | - | `--ignore=vue-caution,functionSize` |
| `--group` | Group results by `file` or `rule` | `rule` | `--group=file` |
| `--order` | Order results (`asc` or `desc`) | `asc` | `--order=desc` |
| `--sort` | Order results `asc` or `desc` | `asc` | `--sort=desc` |
| `--level` | Show only specific level (`error` or `warning`) | Both | `--level=error` |
| `--output` | Output format `text` or `table` or `json` | `text` | `--output=table` |

Expand Down
1,002 changes: 501 additions & 501 deletions dist/vue-mess-detector.es.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/get-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ Options:
| `--apply` | Apply **only** specific rulesets or rules (comma-separated) | All rules | `--apply=vue-essential,magicNumbers` |
| `--ignore` | Ignore **only** specific rulesets or rules (comma-separated) | - | `--ignore=vue-caution,functionSize` |
| `--group` | Group results by `file` or `rule` | `rule` | `--group=file` |
| `--order` | Order results (`asc` or `desc`) | `asc` | `--order=desc` |
| `--sort` | Order results `asc` or `desc` | `asc` | `--sort=desc` |
| `--level` | Show only specific level (`error` or `warning`) | Both | `--level=error` |
| `--output` | Output format `text` or `table` or `json` | `text` | `--output=table` |

Expand Down
6 changes: 3 additions & 3 deletions src/analyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const walkAsync = async (dir: string) => {
}
}

export const analyze = async ({ dir, apply = [], ignore = [], exclude, groupBy, level, orderBy }: AnalyzeParams) => {
export const analyze = async ({ dir, apply = [], ignore = [], exclude, groupBy, level, sortBy }: AnalyzeParams) => {
const appliedRules = apply.filter(rule => !ignore.includes(rule))

const { rulesets, individualRules } = groupRulesByRuleset(appliedRules)
Expand Down Expand Up @@ -95,7 +95,7 @@ export const analyze = async ({ dir, apply = [], ignore = [], exclude, groupBy,
Excluding ${exclude || '-'}
Output level ${BG_INFO}${level}${BG_RESET}
Grouping by ${BG_INFO}${groupBy}${BG_RESET}
Ordering ${BG_INFO}${orderBy}${BG_RESET}`,
Sorting ${BG_INFO}${sortBy}${BG_RESET}`,
})

// Filter out ignored rules from the apply list
Expand All @@ -111,7 +111,7 @@ export const analyze = async ({ dir, apply = [], ignore = [], exclude, groupBy,
output.push({ info: `Found ${BG_INFO}${filesCount}${BG_RESET} files` })

// Generate the report and calculate code health
const { health, output: reportOutput } = reportRules(groupBy, orderBy, level)
const { health, output: reportOutput } = reportRules(groupBy, sortBy, level)
const { errors, warnings, output: codeHealthOutput } = calculateCodeHealth(health, linesCount, filesCount)

if (!errors && !warnings) {
Expand Down
32 changes: 10 additions & 22 deletions src/helpers/validateOption.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,21 @@
import type { Flag, GroupBy, OrderBy, OutputLevel } from '../types'
import { OUTPUT_FORMATS } from '../types'
import { BG_ERR, BG_INFO, BG_RESET, TEXT_INFO, TEXT_RESET } from '../rules/asceeCodes'
import type { Flag } from '../types'
import { GROUP_BY, OUTPUT_FORMATS, OUTPUT_LEVELS, SORT_BY } from '../types'

const validGroupByOptions: GroupBy[] = ['rule', 'file']

/*
- `asc` is the default order, as the checks run.
- `desc` will order the results starting by the most problematic file / rule
The descending order depends on what `groupBy` option is used
- for grouping by file, it will order depending on the file with most offended rules
- for grouping by rule, it will order depending on the rule most offended
*/
const validOrderOptions: OrderBy[] = ['asc', 'desc']
const validOutputLevelOptions: OutputLevel[] = ['all', 'error']

const flagOptions: Record<Flag, GroupBy[] | OrderBy[] | OutputLevel[] | typeof OUTPUT_FORMATS> = {
groupBy: validGroupByOptions,
orderBy: validOrderOptions,
outputLevel: validOutputLevelOptions,
const flagOptions: Record<Flag, typeof GROUP_BY | typeof SORT_BY | typeof OUTPUT_LEVELS | typeof OUTPUT_FORMATS> = {
groupBy: GROUP_BY,
sortBy: SORT_BY,
outputLevel: OUTPUT_LEVELS,
outputFormat: OUTPUT_FORMATS,
}

export const validateOption = <T>(value: T, flag: Flag) => {
const validOptions = flagOptions[flag]

if (!validOptions.includes(value as unknown as GroupBy & OrderBy)) {
if (!Array.isArray(validOptions) || !validOptions.includes(value as any)) {
console.error(
`\nInvalid option "${value}" provided for flag "${flag}". Valid options are: ${validOptions.join(', ')}.\n`,
)
`\nInvalid option ${BG_ERR}${value}${BG_RESET} provided for flag ${TEXT_INFO}${flag}${TEXT_RESET}. Valid options are: ${BG_INFO}${validOptions.join(', ')}${BG_RESET}.\n`,
);
// eslint-disable-next-line node/prefer-global/process
process.exit(1)
}
Expand Down
38 changes: 37 additions & 1 deletion src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import fs from 'node:fs/promises'
import path from 'node:path'
import { afterAll, beforeAll, describe, expect, it } from 'vitest'
import { execa } from 'execa'
import { BG_INFO, BG_RESET } from './rules/asceeCodes'
import { BG_ERR, BG_INFO, BG_RESET, TEXT_INFO, TEXT_RESET } from './rules/asceeCodes'

describe('yarn analyze command with default configuration', () => {
it('should execute without any flags and path', async () => {
Expand Down Expand Up @@ -93,6 +93,42 @@ describe('yarn analyze command with default configuration', () => {
expect(stdout).toContain(`Analyzing Vue, TS and JS files in`)
expect(stdout).toContain(`codeHealthOutput`)
})

it('should execute with group parameter', async () => {
const { stdout } = await execa('yarn', ['analyze', './src/rules/vue-caution', '--group=file'])
expect(stdout).toContain(`- ${TEXT_INFO} src/rules/vue-caution/elementSelectorsWithScoped.ts${TEXT_RESET}`)
})

it('should execute with sort parameter', async () => {
const { stdout } = await execa('yarn', ['analyze', '--sort=asc'])
expect(stdout).toContain(`Analyzing Vue, TS and JS files in`)
})

it('should execute with level parameter', async () => {
const { stdout } = await execa('yarn', ['analyze', '--level=error'])
expect(stdout).toContain(`Analyzing Vue, TS and JS files in`)
})

it('should execute with exclude parameter', async () => {
const { stdout } = await execa('yarn', ['analyze', '--exclude=helpers'])
expect(stdout).toContain('Excluding helpers')
})

it('should execute with table output', async () => {
const { stdout } = await execa('yarn', ['analyze', '--output=table'])
expect(stdout).toContain('Analyzing Vue, TS and JS files in ')
expect(stdout).toContain('┌─') // Table border character
})

it('should error out when invalid value is used for a flag', async () => {
try {
await execa('yarn', ['analyze', '--output=gauranga'])
// If the command doesn't throw, fail the test
expect(true).toBe(false)
} catch (error) {
expect((error as any).stderr).toContain(`Invalid option ${BG_ERR}gauranga${BG_RESET} provided for flag ${TEXT_INFO}outputFormat${TEXT_RESET}. Valid options are: ${BG_INFO}text, json, table${BG_RESET}.`)
}
})
})

describe('yarn analyze command with configuration file', () => {
Expand Down
26 changes: 13 additions & 13 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import Table from 'cli-table3'
import { analyze } from './analyzer'
import { BG_ERR, BG_RESET, TEXT_INFO, TEXT_RESET } from './rules/asceeCodes'
import { RULESETS } from './rules/rules'
import type { GroupBy, OrderBy, OutputFormat, OutputLevel } from './types'
import type { GroupBy, SortBy, OutputFormat, OutputLevel } from './types'
import { validateOption } from './helpers/validateOption'
import getProjectRoot from './helpers/getProjectRoot'
import coerceRules from './helpers/coerceRules'
import { FLAT_RULESETS_RULES } from './helpers/constants'
import { OUTPUT_FORMATS } from './types'
import { GROUP_BY, SORT_BY, OUTPUT_FORMATS, OUTPUT_LEVELS } from './types'
import { getPackageJson } from './helpers/getPackageJson'

// eslint-disable-next-line node/prefer-global/process
Expand All @@ -28,7 +28,7 @@ let config = {
exclude: undefined,
group: 'rule',
level: 'all',
order: 'desc',
sort: 'desc',
output: 'text',
}

Expand Down Expand Up @@ -71,15 +71,15 @@ yargs(hideBin(process.argv))
.option('group', {
alias: 'g',
describe: 'Group results at the output',
choices: ['rule', 'file'],
choices: GROUP_BY,
coerce: value => validateOption<GroupBy>(value, 'groupBy'),
default: config.group,
group: 'Group Results:',
})
.option('level', {
alias: 'l',
describe: 'Output level',
choices: ['all', 'error'],
choices: OUTPUT_LEVELS,
coerce: value => validateOption<OutputLevel>(value, 'outputLevel'),
default: config.level,
group: 'Output:',
Expand All @@ -91,13 +91,13 @@ yargs(hideBin(process.argv))
default: config.ignore,
group: 'Filter Rulesets:',
})
.option('order', {
alias: 'o',
describe: 'Order results at the output',
choices: ['asc', 'desc'],
coerce: value => validateOption<OrderBy>(value, 'orderBy'),
default: config.order,
group: 'Order Results:',
.option('sort', {
alias: 's',
describe: 'Sort results at the output',
choices: SORT_BY,
coerce: value => validateOption<SortBy>(value, 'sortBy'),
default: config.sort,
group: 'Sort Results:',
})
.option('output', {
describe: 'Output format',
Expand All @@ -114,7 +114,7 @@ yargs(hideBin(process.argv))
exclude: argv.exclude,
groupBy: argv.group,
level: argv.level,
orderBy: argv.order,
sortBy: argv.sort,
})
.then((result) => {
if (argv.output == 'text') {
Expand Down
8 changes: 4 additions & 4 deletions src/rulesReport.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { GroupBy, Health, Offense, OffensesGrouped, OrderBy, OutputLevel, ReportFunction } from './types'
import type { GroupBy, Health, Offense, OffensesGrouped, OutputLevel, ReportFunction, SortBy } from './types'
import { BG_ERR } from './rules/asceeCodes'

import { reportElementSelectorsWithScoped, reportImplicitParentChildCommunication } from './rules/vue-caution'
Expand All @@ -12,7 +12,7 @@ interface OutputType {
[key: string]: { id: string, description: string, message: string }[]
}

export const reportRules = (groupBy: GroupBy, orderBy: OrderBy, level: OutputLevel) => {
export const reportRules = (groupBy: GroupBy, sortBy: SortBy, level: OutputLevel) => {
const offensesGrouped: OffensesGrouped = {}
const health: Health[] = []

Expand Down Expand Up @@ -85,12 +85,12 @@ export const reportRules = (groupBy: GroupBy, orderBy: OrderBy, level: OutputLev
processOffenses(reportVForWithIndexKey)
processOffenses(reportZeroLengthComparison)

// Sort offenses grouped by key based on the `orderBy` parameter
// Sort offenses grouped by key based on the `sortBy` parameter
const sortedKeys = Object.keys(offensesGrouped).sort((a, b) => {
const countA = offensesGrouped[a].length
const countB = offensesGrouped[b].length

if (orderBy === 'desc') {
if (sortBy === 'desc') {
return countB - countA
}

Expand Down
25 changes: 19 additions & 6 deletions src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,32 @@
export type Flag = 'groupBy' | 'orderBy' | 'outputLevel' | 'outputFormat'
export type GroupBy = 'rule' | 'file'
export type OrderBy = 'asc' | 'desc'
export type OutputLevel = 'all' | 'error'
// TODO refactor the above to be like ouput formats - validateOption and src/index.ts should be also changed
export type Flag = 'groupBy' | 'sortBy' | 'outputLevel' | 'outputFormat'
/*
- `asc` is the default order, as the checks run.
- `desc` will order the results starting by the most problematic file / rule
The descending order depends on what `groupBy` option is used
- for grouping by file, it will order depending on the file with most offended rules
- for grouping by rule, it will order depending on the rule most offended
*/
export const GROUP_BY = ['rule', 'file'] as const
export type GroupBy = typeof GROUP_BY[number]

export const SORT_BY = ['asc', 'desc'] as const
export type SortBy = typeof SORT_BY[number]

export const OUTPUT_FORMATS = ['text', 'json', 'table'] as const
export type OutputFormat = typeof OUTPUT_FORMATS[number]

export const OUTPUT_LEVELS = ['all', 'error'] as const
export type OutputLevel = typeof OUTPUT_LEVELS[number]

export interface AnalyzeParams {
dir: string
apply: string[]
ignore?: string[]
exclude: string
groupBy: GroupBy
level: OutputLevel
orderBy: OrderBy
sortBy: SortBy
}

export interface Offense {
Expand Down

0 comments on commit 892d576

Please sign in to comment.