Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: move rules into dedicated attribute #476

Merged
merged 2 commits into from
Jul 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/cli/htmlhint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ function hintFile(filepath: string, ruleset?: Ruleset) {
// ignore
}

return HTMLHint.verify(content, ruleset)
return HTMLHint.verify(content, { rules: ruleset })
}

// hint stdin
Expand All @@ -483,7 +483,7 @@ function hintStdin(

process.stdin.on('end', () => {
const content = buffers.join('')
const messages = HTMLHint.verify(content, ruleset)
const messages = HTMLHint.verify(content, { rules: ruleset })
callback(messages)
})
}
Expand All @@ -496,7 +496,7 @@ function hintUrl(
) {
request.get(url, (error, response, body) => {
if (!error && response.statusCode == 200) {
const messages = HTMLHint.verify(body, ruleset)
const messages = HTMLHint.verify(body, { rules: ruleset })
callback(messages)
} else {
callback([])
Expand Down
15 changes: 13 additions & 2 deletions src/core/core.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import HTMLParser from './htmlparser'
import Reporter, { ReportMessageCallback } from './reporter'
import * as HTMLRules from './rules'
import { Hint, isRuleSeverity, Rule, Ruleset, RuleSeverity } from './types'
import {
Configuration,
Hint,
isRuleSeverity,
Rule,
Ruleset,
RuleSeverity,
} from './types'

export interface FormatOptions {
colors?: boolean
Expand All @@ -27,7 +34,11 @@ class HTMLHintCore {
this.rules[rule.id] = rule
}

public verify(html: string, ruleset: Ruleset = this.defaultRuleset) {
public verify(
html: string,
config: Configuration = { rules: this.defaultRuleset }
) {
let ruleset = config.rules ?? this.defaultRuleset
if (Object.keys(ruleset).length === 0) {
ruleset = this.defaultRuleset
}
Expand Down
4 changes: 4 additions & 0 deletions src/core/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { HTMLParser } from './core'
import { ReportMessageCallback } from './reporter'

export interface Configuration {
rules?: Ruleset
}

export interface Rule {
id: string
description: string
Expand Down
24 changes: 17 additions & 7 deletions test/core.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const HTMLHint = require('../dist/htmlhint.js').HTMLHint
describe('Core', () => {
it('Set false to rule no effected should result in an error', () => {
const code = '<img src="test.gif" />'
const messages = HTMLHint.verify(code, { 'alt-require': 'off' })
const messages = HTMLHint.verify(code, { rules: { 'alt-require': 'off' } })
expect(messages.length).to.be(0)
})

Expand All @@ -27,7 +27,9 @@ describe('Core', () => {
// With value = 'error'
let code = '<!-- htmlhint alt-require:error -->\r\n<img src="test.gif" />'
let messages = HTMLHint.verify(code, {
'alt-require': 'off',
rules: {
'alt-require': 'off',
},
})

expect(messages.length).to.be(1)
Expand All @@ -38,7 +40,9 @@ describe('Core', () => {
// Without value
code = '<!-- htmlhint alt-require -->\r\n<img src="test.gif" />'
messages = HTMLHint.verify(code, {
'alt-require': 'off',
rules: {
'alt-require': 'off',
},
})

expect(messages.length).to.be(1)
Expand All @@ -49,14 +53,18 @@ describe('Core', () => {
// With value = 'off'
code = '<!-- htmlhint alt-require:off -->\r\n<img src="test.gif" />'
messages = HTMLHint.verify(code, {
'alt-require': 'error',
rules: {
'alt-require': 'error',
},
})
expect(messages.length).to.be(0)

// Without rule
code = '<!-- htmlhint -->\r\n<img src="test.gif" />'
messages = HTMLHint.verify(code, {
'alt-require': 'off',
rules: {
'alt-require': 'off',
},
})

expect(messages.length).to.be(0)
Expand All @@ -66,8 +74,10 @@ describe('Core', () => {
const code =
'tttttttttttttttttttttttttttttttttttt<div>中文<img src="test.gif" />tttttttttttttttttttttttttttttttttttttttttttttt'
const messages = HTMLHint.verify(code, {
'tag-pair': 'error',
'alt-require': 'error',
rules: {
'tag-pair': 'error',
'alt-require': 'error',
},
})
let arrLogs = HTMLHint.format(messages)
expect(arrLogs.length).to.be(4)
Expand Down
26 changes: 13 additions & 13 deletions test/rules/alt-require.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ ruleOptions[ruldId] = 'warn'
describe(`Rules: ${ruldId}`, () => {
it('Img tag have empty alt attribute should not result in an error', () => {
const code = '<img width="200" height="300" alt="">'
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(0)
})

it('Img tag have non empty alt attribute should not result in an error', () => {
const code = '<img width="200" height="300" alt="test">'
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(0)
})

it('Img tag have not alt attribute should result in an error', () => {
const code = '<img width="200" height="300">'
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(1)
expect(messages[0].rule.id).to.be(ruldId)
expect(messages[0].line).to.be(1)
Expand All @@ -33,19 +33,19 @@ describe(`Rules: ${ruldId}`, () => {
/* A tag can have shape and coords attributes and not have alt attribute */
it('A tag have not alt attribute should not result in an error', () => {
const code = '<a>'
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(0)
})

it('Area tag have not href and alt attributes should not result in an error', () => {
const code = '<area>'
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(0)
})

it('Area[href] tag have not alt attribute should result in an error', () => {
const code = '<area href="#test">'
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(1)
expect(messages[0].rule.id).to.be(ruldId)
expect(messages[0].line).to.be(1)
Expand All @@ -55,7 +55,7 @@ describe(`Rules: ${ruldId}`, () => {

it('Area[href] tag have empty alt attribute should result in an error', () => {
const code = '<area href="#test" alt="">'
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(1)
expect(messages[0].rule.id).to.be(ruldId)
expect(messages[0].line).to.be(1)
Expand All @@ -65,25 +65,25 @@ describe(`Rules: ${ruldId}`, () => {

it('Area[href] tag have non emtpy alt attribute should not result in an error', () => {
const code = '<area href="#test" alt="test">'
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(0)
})

it('Input tag have not type and alt attributes should not result in an error', () => {
const code = '<input>'
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(0)
})

it('Input[type="text"] tag have not alt attribute should not result in an error', () => {
const code = '<input type="text">'
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(0)
})

it('Input[type="image"] tag have not alt attribute should result in an error', () => {
const code = '<input type="image">'
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(1)
expect(messages[0].rule.id).to.be(ruldId)
expect(messages[0].line).to.be(1)
Expand All @@ -93,7 +93,7 @@ describe(`Rules: ${ruldId}`, () => {

it('Input[type="image"] tag have empty alt attribute should result in an error', () => {
const code = '<input type="image" alt="">'
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(1)
expect(messages[0].rule.id).to.be(ruldId)
expect(messages[0].line).to.be(1)
Expand All @@ -103,7 +103,7 @@ describe(`Rules: ${ruldId}`, () => {

it('Input[type="image"] tag have non emtpy alt attribute should not result in an error', () => {
const code = '<input type="image" alt="test">'
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(0)
})
})
14 changes: 7 additions & 7 deletions test/rules/attr-lowercase.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ ruleOptions[ruldId] = 'error'
describe(`Rules: ${ruldId}`, () => {
it('Not all lowercase attr should result in an error', () => {
let code = '<p TEST="abc">'
let messages = HTMLHint.verify(code, ruleOptions)
let messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(1)
expect(messages[0].rule.id).to.be(ruldId)
expect(messages[0].line).to.be(1)
expect(messages[0].col).to.be(3)

code = '<p id=""\r\n TEST1="abc" TEST2="abc">'
messages = HTMLHint.verify(code, ruleOptions)
messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(2)
expect(messages[0].rule.id).to.be(ruldId)
expect(messages[0].line).to.be(2)
Expand All @@ -29,35 +29,35 @@ describe(`Rules: ${ruldId}`, () => {

it('Lowercase attr should not result in an error', () => {
const code = '<p test="abc">'
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(0)
})

it('Set is false should not result in an error', () => {
const code = '<p TEST="abc">'
ruleOptions[ruldId] = 'off'
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(0)
})

it('Set to array list should not result in an error', () => {
const code = '<p testBox="abc" tttAAA="ccc">'
ruleOptions[ruldId] = ['error', { exceptions: ['testBox', 'tttAAA'] }]
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(0)
})

it('Set to array list with RegExp should not result in an error', () => {
const code = '<p testBox="abc" bind:tapTop="ccc">'
ruleOptions[ruldId] = ['error', { exceptions: ['testBox', /bind:.*/] }]
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(0)
})

it('Set to array list with regex string should not result in an error', () => {
const code = '<p testBox="abc" [ngFor]="ccc">'
ruleOptions[ruldId] = ['error', { exceptions: ['testBox', '/\\[.*\\]/'] }]
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(0)
})
})
4 changes: 2 additions & 2 deletions test/rules/attr-no-duplication.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ruleOptions[ruldId] = 'error'
describe(`Rules: ${ruldId}`, () => {
it('Attribute name been duplication should result in an error', () => {
const code = '<a href="a" href="b">bbb</a>'
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(1)
expect(messages[0].rule.id).to.be(ruldId)
expect(messages[0].line).to.be(1)
Expand All @@ -19,7 +19,7 @@ describe(`Rules: ${ruldId}`, () => {

it('Attribute name not been duplication should not result in an error', () => {
const code = '<a href="a">bbb</a>'
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(0)
})
})
4 changes: 2 additions & 2 deletions test/rules/attr-no-unnecessary-whitespace.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe(`Rules: ${ruldId}`, () => {
'<div title ="a" />',
]
for (let i = 0; i < codes.length; i++) {
const messages = HTMLHint.verify(codes[i], ruleOptions)
const messages = HTMLHint.verify(codes[i], { rules: ruleOptions })
expect(messages.length).to.be(1)
expect(messages[0].rule.id).to.be(ruldId)
expect(messages[0].line).to.be(1)
Expand All @@ -26,7 +26,7 @@ describe(`Rules: ${ruldId}`, () => {
it('Attribute without spaces should not result in an error', () => {
const codes = ['<div title="a" />', '<div title="a = a" />']
for (let i = 0; i < codes.length; i++) {
const messages = HTMLHint.verify(codes[i], ruleOptions)
const messages = HTMLHint.verify(codes[i], { rules: ruleOptions })
expect(messages.length).to.be(0)
}
})
Expand Down
6 changes: 3 additions & 3 deletions test/rules/attr-sort.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ describe(`Rules: ${ruleId}`, () => {
it('Attribute unsorted tags must result in an error', () => {
const code = '<div id="test" class="class" title="tite"></div>'

const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })

expect(messages.length).to.be(1)
expect(messages[0].rule.id).to.be(ruleId)
Expand All @@ -21,15 +21,15 @@ describe(`Rules: ${ruleId}`, () => {
it('Attribute unsorted tags that are unrecognizable should not throw error', () => {
const code = '<div img="image" meta="meta" font="font"></div>'

const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })

expect(messages.length).to.be(0)
})

it('Attribute unsorted of tags of various types should throw error', () => {
const code = '<div type="type" img="image" id="id" font="font"></div>'

const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })

expect(messages.length).to.be(1)
expect(messages[0].rule.id).to.be(ruleId)
Expand Down
6 changes: 3 additions & 3 deletions test/rules/attr-unsafe-chars.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ describe(`Rules: ${ruldId}`, () => {
it('Attribute value have unsafe chars should result in an error', () => {
const code =
'<a href="https://vimeo.com/album/1951235/video/56931059‎">Sud Web 2012</a>'
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(1)
expect(messages[0].rule.id).to.be(ruldId)
expect(messages[0].line).to.be(1)
Expand All @@ -21,14 +21,14 @@ describe(`Rules: ${ruldId}`, () => {

it('Attribute value have no unsafe chars should not result in an error', () => {
const code = '<input disabled="disabled" />'
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(0)
})

it('Attribute value have \\r\\n\\t should not result in an error', () => {
const code =
'<link rel="icon" type="image/x-icon" href="data:image/x-icon;base64,R0lGODlhEAAQAKEAAAAAAICAgP///wAAACH/\nC05FVFNDQVBFMi4wAwEAAAAh/hFDcmVhdGVkIHdpdGggR0lNUAAh+QQBZAADACwAAAAAEAAQAAACJIyPacLtvp5kEUwYmL00i81VXK\neNgjiioQdeqsuakXl6tIIjBQAh+QQBZAADACwAAAAAEAAQAAACIIyPacLtvp5kcb5qG85iZ2+BkyiRV8BBaEqtrKkqslEAADs=\t"/>'
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(0)
})
})
4 changes: 2 additions & 2 deletions test/rules/attr-value-double-quotes.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ruleOptions[ruldId] = 'error'
describe(`Rules: ${ruldId}`, () => {
it('Attribute value closed by single quotes should result in an error', () => {
const code = "<a href='abc' title=abc style=''>"
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(3)
expect(messages[0].rule.id).to.be(ruldId)
expect(messages[0].line).to.be(1)
Expand All @@ -25,7 +25,7 @@ describe(`Rules: ${ruldId}`, () => {

it('Attribute value no closed should not result in an error', () => {
const code = '<input type="button" disabled style="">'
const messages = HTMLHint.verify(code, ruleOptions)
const messages = HTMLHint.verify(code, { rules: ruleOptions })
expect(messages.length).to.be(0)
})
})
Loading