Skip to content

Commit d0c71dd

Browse files
author
Shinigami
committed
feat: move rules into dedicated attribute (#476)
* feat: move rules into dedicated attribute * test: update tests
1 parent 36ff063 commit d0c71dd

36 files changed

+196
-169
lines changed

src/cli/htmlhint.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ function hintFile(filepath: string, ruleset?: Ruleset) {
465465
// ignore
466466
}
467467

468-
return HTMLHint.verify(content, ruleset)
468+
return HTMLHint.verify(content, { rules: ruleset })
469469
}
470470

471471
// hint stdin
@@ -483,7 +483,7 @@ function hintStdin(
483483

484484
process.stdin.on('end', () => {
485485
const content = buffers.join('')
486-
const messages = HTMLHint.verify(content, ruleset)
486+
const messages = HTMLHint.verify(content, { rules: ruleset })
487487
callback(messages)
488488
})
489489
}
@@ -496,7 +496,7 @@ function hintUrl(
496496
) {
497497
request.get(url, (error, response, body) => {
498498
if (!error && response.statusCode == 200) {
499-
const messages = HTMLHint.verify(body, ruleset)
499+
const messages = HTMLHint.verify(body, { rules: ruleset })
500500
callback(messages)
501501
} else {
502502
callback([])

src/core/core.ts

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
import HTMLParser from './htmlparser'
22
import Reporter, { ReportMessageCallback } from './reporter'
33
import * as HTMLRules from './rules'
4-
import { Hint, isRuleSeverity, Rule, Ruleset, RuleSeverity } from './types'
4+
import {
5+
Configuration,
6+
Hint,
7+
isRuleSeverity,
8+
Rule,
9+
Ruleset,
10+
RuleSeverity,
11+
} from './types'
512

613
export interface FormatOptions {
714
colors?: boolean
@@ -27,7 +34,11 @@ class HTMLHintCore {
2734
this.rules[rule.id] = rule
2835
}
2936

30-
public verify(html: string, ruleset: Ruleset = this.defaultRuleset) {
37+
public verify(
38+
html: string,
39+
config: Configuration = { rules: this.defaultRuleset }
40+
) {
41+
let ruleset = config.rules ?? this.defaultRuleset
3142
if (Object.keys(ruleset).length === 0) {
3243
ruleset = this.defaultRuleset
3344
}

src/core/types.ts

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { HTMLParser } from './core'
22
import { ReportMessageCallback } from './reporter'
33

4+
export interface Configuration {
5+
rules?: Ruleset
6+
}
7+
48
export interface Rule {
59
id: string
610
description: string

test/core.spec.js

+17-7
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const HTMLHint = require('../dist/htmlhint.js').HTMLHint
55
describe('Core', () => {
66
it('Set false to rule no effected should result in an error', () => {
77
const code = '<img src="test.gif" />'
8-
const messages = HTMLHint.verify(code, { 'alt-require': 'off' })
8+
const messages = HTMLHint.verify(code, { rules: { 'alt-require': 'off' } })
99
expect(messages.length).to.be(0)
1010
})
1111

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

3335
expect(messages.length).to.be(1)
@@ -38,7 +40,9 @@ describe('Core', () => {
3840
// Without value
3941
code = '<!-- htmlhint alt-require -->\r\n<img src="test.gif" />'
4042
messages = HTMLHint.verify(code, {
41-
'alt-require': 'off',
43+
rules: {
44+
'alt-require': 'off',
45+
},
4246
})
4347

4448
expect(messages.length).to.be(1)
@@ -49,14 +53,18 @@ describe('Core', () => {
4953
// With value = 'off'
5054
code = '<!-- htmlhint alt-require:off -->\r\n<img src="test.gif" />'
5155
messages = HTMLHint.verify(code, {
52-
'alt-require': 'error',
56+
rules: {
57+
'alt-require': 'error',
58+
},
5359
})
5460
expect(messages.length).to.be(0)
5561

5662
// Without rule
5763
code = '<!-- htmlhint -->\r\n<img src="test.gif" />'
5864
messages = HTMLHint.verify(code, {
59-
'alt-require': 'off',
65+
rules: {
66+
'alt-require': 'off',
67+
},
6068
})
6169

6270
expect(messages.length).to.be(0)
@@ -66,8 +74,10 @@ describe('Core', () => {
6674
const code =
6775
'tttttttttttttttttttttttttttttttttttt<div>中文<img src="test.gif" />tttttttttttttttttttttttttttttttttttttttttttttt'
6876
const messages = HTMLHint.verify(code, {
69-
'tag-pair': 'error',
70-
'alt-require': 'error',
77+
rules: {
78+
'tag-pair': 'error',
79+
'alt-require': 'error',
80+
},
7181
})
7282
let arrLogs = HTMLHint.format(messages)
7383
expect(arrLogs.length).to.be(4)

test/rules/alt-require.spec.js

+13-13
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@ ruleOptions[ruldId] = 'warn'
1010
describe(`Rules: ${ruldId}`, () => {
1111
it('Img tag have empty alt attribute should not result in an error', () => {
1212
const code = '<img width="200" height="300" alt="">'
13-
const messages = HTMLHint.verify(code, ruleOptions)
13+
const messages = HTMLHint.verify(code, { rules: ruleOptions })
1414
expect(messages.length).to.be(0)
1515
})
1616

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

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

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

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

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

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

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

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

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

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

104104
it('Input[type="image"] tag have non emtpy alt attribute should not result in an error', () => {
105105
const code = '<input type="image" alt="test">'
106-
const messages = HTMLHint.verify(code, ruleOptions)
106+
const messages = HTMLHint.verify(code, { rules: ruleOptions })
107107
expect(messages.length).to.be(0)
108108
})
109109
})

test/rules/attr-lowercase.spec.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ ruleOptions[ruldId] = 'error'
1010
describe(`Rules: ${ruldId}`, () => {
1111
it('Not all lowercase attr should result in an error', () => {
1212
let code = '<p TEST="abc">'
13-
let messages = HTMLHint.verify(code, ruleOptions)
13+
let messages = HTMLHint.verify(code, { rules: ruleOptions })
1414
expect(messages.length).to.be(1)
1515
expect(messages[0].rule.id).to.be(ruldId)
1616
expect(messages[0].line).to.be(1)
1717
expect(messages[0].col).to.be(3)
1818

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

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

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

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

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

5757
it('Set to array list with regex string should not result in an error', () => {
5858
const code = '<p testBox="abc" [ngFor]="ccc">'
5959
ruleOptions[ruldId] = ['error', { exceptions: ['testBox', '/\\[.*\\]/'] }]
60-
const messages = HTMLHint.verify(code, ruleOptions)
60+
const messages = HTMLHint.verify(code, { rules: ruleOptions })
6161
expect(messages.length).to.be(0)
6262
})
6363
})

test/rules/attr-no-duplication.spec.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ ruleOptions[ruldId] = 'error'
1010
describe(`Rules: ${ruldId}`, () => {
1111
it('Attribute name been duplication should result in an error', () => {
1212
const code = '<a href="a" href="b">bbb</a>'
13-
const messages = HTMLHint.verify(code, ruleOptions)
13+
const messages = HTMLHint.verify(code, { rules: ruleOptions })
1414
expect(messages.length).to.be(1)
1515
expect(messages[0].rule.id).to.be(ruldId)
1616
expect(messages[0].line).to.be(1)
@@ -19,7 +19,7 @@ describe(`Rules: ${ruldId}`, () => {
1919

2020
it('Attribute name not been duplication should not result in an error', () => {
2121
const code = '<a href="a">bbb</a>'
22-
const messages = HTMLHint.verify(code, ruleOptions)
22+
const messages = HTMLHint.verify(code, { rules: ruleOptions })
2323
expect(messages.length).to.be(0)
2424
})
2525
})

test/rules/attr-no-unnecessary-whitespace.spec.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ describe(`Rules: ${ruldId}`, () => {
1515
'<div title ="a" />',
1616
]
1717
for (let i = 0; i < codes.length; i++) {
18-
const messages = HTMLHint.verify(codes[i], ruleOptions)
18+
const messages = HTMLHint.verify(codes[i], { rules: ruleOptions })
1919
expect(messages.length).to.be(1)
2020
expect(messages[0].rule.id).to.be(ruldId)
2121
expect(messages[0].line).to.be(1)
@@ -26,7 +26,7 @@ describe(`Rules: ${ruldId}`, () => {
2626
it('Attribute without spaces should not result in an error', () => {
2727
const codes = ['<div title="a" />', '<div title="a = a" />']
2828
for (let i = 0; i < codes.length; i++) {
29-
const messages = HTMLHint.verify(codes[i], ruleOptions)
29+
const messages = HTMLHint.verify(codes[i], { rules: ruleOptions })
3030
expect(messages.length).to.be(0)
3131
}
3232
})

test/rules/attr-sort.spec.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ describe(`Rules: ${ruleId}`, () => {
1111
it('Attribute unsorted tags must result in an error', () => {
1212
const code = '<div id="test" class="class" title="tite"></div>'
1313

14-
const messages = HTMLHint.verify(code, ruleOptions)
14+
const messages = HTMLHint.verify(code, { rules: ruleOptions })
1515

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

24-
const messages = HTMLHint.verify(code, ruleOptions)
24+
const messages = HTMLHint.verify(code, { rules: ruleOptions })
2525

2626
expect(messages.length).to.be(0)
2727
})
2828

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

32-
const messages = HTMLHint.verify(code, ruleOptions)
32+
const messages = HTMLHint.verify(code, { rules: ruleOptions })
3333

3434
expect(messages.length).to.be(1)
3535
expect(messages[0].rule.id).to.be(ruleId)

test/rules/attr-unsafe-chars.spec.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ describe(`Rules: ${ruldId}`, () => {
1111
it('Attribute value have unsafe chars should result in an error', () => {
1212
const code =
1313
'<a href="https://vimeo.com/album/1951235/video/56931059‎">Sud Web 2012</a>'
14-
const messages = HTMLHint.verify(code, ruleOptions)
14+
const messages = HTMLHint.verify(code, { rules: ruleOptions })
1515
expect(messages.length).to.be(1)
1616
expect(messages[0].rule.id).to.be(ruldId)
1717
expect(messages[0].line).to.be(1)
@@ -21,14 +21,14 @@ describe(`Rules: ${ruldId}`, () => {
2121

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

2828
it('Attribute value have \\r\\n\\t should not result in an error', () => {
2929
const code =
3030
'<link rel="icon" type="image/x-icon" href="data:image/x-icon;base64,R0lGODlhEAAQAKEAAAAAAICAgP///wAAACH/\nC05FVFNDQVBFMi4wAwEAAAAh/hFDcmVhdGVkIHdpdGggR0lNUAAh+QQBZAADACwAAAAAEAAQAAACJIyPacLtvp5kEUwYmL00i81VXK\neNgjiioQdeqsuakXl6tIIjBQAh+QQBZAADACwAAAAAEAAQAAACIIyPacLtvp5kcb5qG85iZ2+BkyiRV8BBaEqtrKkqslEAADs=\t"/>'
31-
const messages = HTMLHint.verify(code, ruleOptions)
31+
const messages = HTMLHint.verify(code, { rules: ruleOptions })
3232
expect(messages.length).to.be(0)
3333
})
3434
})

test/rules/attr-value-double-quotes.spec.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ ruleOptions[ruldId] = 'error'
1010
describe(`Rules: ${ruldId}`, () => {
1111
it('Attribute value closed by single quotes should result in an error', () => {
1212
const code = "<a href='abc' title=abc style=''>"
13-
const messages = HTMLHint.verify(code, ruleOptions)
13+
const messages = HTMLHint.verify(code, { rules: ruleOptions })
1414
expect(messages.length).to.be(3)
1515
expect(messages[0].rule.id).to.be(ruldId)
1616
expect(messages[0].line).to.be(1)
@@ -25,7 +25,7 @@ describe(`Rules: ${ruldId}`, () => {
2525

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

0 commit comments

Comments
 (0)