Skip to content

Commit

Permalink
Merge branch 'main' of github.com:rrd108/vue-mess-detector
Browse files Browse the repository at this point in the history
  • Loading branch information
rrd108 committed Aug 9, 2024
2 parents 36b72a8 + c816221 commit a8c4fd2
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 29 deletions.
44 changes: 28 additions & 16 deletions src/rules/vue-caution/elementSelectorsWithScoped.test.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,49 @@
import { describe, expect, it, vi } from 'vitest'
import { beforeEach, describe, expect, it } from 'vitest'
import type { SFCStyleBlock } from '@vue/compiler-sfc'
import { BG_RESET, BG_WARN } from '../asceeCodes'
import { checkElementSelectorsWithScoped, reportElementSelectorsWithScoped } from './elementSelectorsWithScoped'

const mockConsoleLog = vi.spyOn(console, 'log').mockImplementation(() => {})
import { BG_RESET, BG_WARN, TEXT_INFO, TEXT_RESET, TEXT_WARN } from '../asceeCodes'
import { checkElementSelectorsWithScoped, reportElementSelectorsWithScoped, resetElementSelectorWithScoped } from './elementSelectorsWithScoped'

describe('checkElementSelectorsWithScoped', () => {
beforeEach(() => {
resetElementSelectorWithScoped()
})

it('should not report non-element selectors', () => {
const styles = [{ content: '.my-class { font-size: 14px; }', scoped: true }] as SFCStyleBlock[]
const filePath = 'non-element-selectors.vue'
checkElementSelectorsWithScoped(styles, filePath)
expect(reportElementSelectorsWithScoped()).toBe(0)
expect(mockConsoleLog).not.toHaveBeenCalled()
expect(reportElementSelectorsWithScoped().length).toBe(0)
expect(reportElementSelectorsWithScoped()).toStrictEqual([])
})

it('should report element selectors in the valid HTML tags list', () => {
const styles = [{ content: 'button { background: blue; }', scoped: true }] as SFCStyleBlock[]
const filename = 'element-selectors.vue'
checkElementSelectorsWithScoped(styles, filename)
expect(reportElementSelectorsWithScoped()).toBe(1)
expect(mockConsoleLog).toHaveBeenCalled()
expect(mockConsoleLog).toHaveBeenLastCalledWith(
` - ${filename} 🚨 ${BG_WARN}(button)${BG_RESET}`,
)
expect(reportElementSelectorsWithScoped().length).toBe(1)
expect(reportElementSelectorsWithScoped()).toStrictEqual([{
file: filename,
rule: `${TEXT_INFO}vue-caution ~ element selectors with scoped${TEXT_RESET}`,
description: `👉 ${TEXT_WARN}Prefer class selectors over element selectors in scoped styles, because large numbers of element selectors are slow.${TEXT_RESET} See: https://vuejs.org/style-guide/rules-use-with-caution.html#element-selectors-with-scoped`,
message: `${BG_WARN}(button)${BG_RESET} 🚨`,
}])
})

it('should handle multiple element selectors', () => {
const styles = [{ content: 'button { background: blue; } div { color: red; }', scoped: true }] as SFCStyleBlock[]
const filename = 'multiple-element-selectors.vue'
checkElementSelectorsWithScoped(styles, filename)
expect(reportElementSelectorsWithScoped()).toBe(3)
expect(mockConsoleLog).toHaveBeenLastCalledWith(
` - ${filename} 🚨 ${BG_WARN}(div)${BG_RESET}`,
)
expect(reportElementSelectorsWithScoped().length).toBe(2)
expect(reportElementSelectorsWithScoped()).toStrictEqual([{
file: filename,
rule: `${TEXT_INFO}vue-caution ~ element selectors with scoped${TEXT_RESET}`,
description: `👉 ${TEXT_WARN}Prefer class selectors over element selectors in scoped styles, because large numbers of element selectors are slow.${TEXT_RESET} See: https://vuejs.org/style-guide/rules-use-with-caution.html#element-selectors-with-scoped`,
message: `${BG_WARN}(button)${BG_RESET} 🚨`,
}, {
file: filename,
rule: `${TEXT_INFO}vue-caution ~ element selectors with scoped${TEXT_RESET}`,
description: `👉 ${TEXT_WARN}Prefer class selectors over element selectors in scoped styles, because large numbers of element selectors are slow.${TEXT_RESET} See: https://vuejs.org/style-guide/rules-use-with-caution.html#element-selectors-with-scoped`,
message: `${BG_WARN}(div)${BG_RESET} 🚨`,
}])
})
})
27 changes: 14 additions & 13 deletions src/rules/vue-caution/elementSelectorsWithScoped.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { SFCStyleBlock } from '@vue/compiler-sfc'
import type { HtmlTags } from 'html-tags'
import htmlTags from 'html-tags'
import { BG_RESET, BG_WARN, TEXT_INFO, TEXT_RESET, TEXT_WARN } from '../asceeCodes'
import { getUniqueFilenameCount } from '../../helpers'
import type { Offense } from '../../types'

interface ElementSelectorsWithScoped {
filename: string
Expand Down Expand Up @@ -30,21 +30,22 @@ const checkElementSelectorsWithScoped = (styles: SFCStyleBlock[] | null, filePat
}

const reportElementSelectorsWithScoped = () => {
const offenses: Offense[] = []

if (elementSelectorsWithScopedFiles.length > 0) {
// Count only non duplicated objects (by its `filename` property)
const fileCount = getUniqueFilenameCount<ElementSelectorsWithScoped>(elementSelectorsWithScopedFiles, 'filename')

console.log(
`\n${TEXT_INFO}vue-caution${TEXT_RESET} ${BG_WARN}element selectors with scoped${BG_RESET} found in ${fileCount} files.`,
)
console.log(
`👉 ${TEXT_WARN}Prefer class selectors over element selectors in scoped styles, because large numbers of element selectors are slow.${TEXT_RESET} See: https://vuejs.org/style-guide/rules-use-with-caution.html#element-selectors-with-scoped`,
)
elementSelectorsWithScopedFiles.forEach((file) => {
console.log(` - ${file.filename} 🚨 ${BG_WARN}(${file.selector})${BG_RESET}`)
offenses.push({
file: file.filename,
rule: `${TEXT_INFO}vue-caution ~ element selectors with scoped${TEXT_RESET}`,
description: `👉 ${TEXT_WARN}Prefer class selectors over element selectors in scoped styles, because large numbers of element selectors are slow.${TEXT_RESET} See: https://vuejs.org/style-guide/rules-use-with-caution.html#element-selectors-with-scoped`,
message: `${BG_WARN}(${file.selector})${BG_RESET} 🚨`,
})
})
}
return elementSelectorsWithScopedFiles.length

return offenses
}

export { checkElementSelectorsWithScoped, reportElementSelectorsWithScoped }
const resetElementSelectorWithScoped = () => (elementSelectorsWithScopedFiles.length = 0)

export { checkElementSelectorsWithScoped, reportElementSelectorsWithScoped, resetElementSelectorWithScoped }

0 comments on commit a8c4fd2

Please sign in to comment.