Skip to content

Commit 3bc82c6

Browse files
committed
Add a rule which shows an error when template can't be parsed by pug
1 parent 18f4850 commit 3bc82c6

File tree

5 files changed

+124
-11
lines changed

5 files changed

+124
-11
lines changed

index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
/* eslint-disable global-require */
77
const allRules = {
8+
'no-broken-template': require('./lib/rules/no-broken-template'),
89
'no-undef': require('./lib/rules/no-undef'),
910
'uses-react': require('./lib/rules/uses-react'),
1011
'uses-vars': require('./lib/rules/uses-vars'),
@@ -19,6 +20,7 @@ module.exports = {
1920
pug: true,
2021
},
2122
rules: {
23+
'react-pug/no-broken-template': 2,
2224
'react-pug/no-undef': 2,
2325
'react-pug/uses-react': 2,
2426
'react-pug/uses-vars': 2,

lib/rules/no-broken-template.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* @fileoverview Disallow broken template
3+
* @author Eugene Zhlobo
4+
*/
5+
6+
const { findVariablesInTemplate } = require('pug-uses-variables')
7+
const { isReactPugReference, getTemplate, buildLocation } = require('../utilities')
8+
9+
//------------------------------------------------------------------------------
10+
// Rule Definition
11+
//------------------------------------------------------------------------------
12+
13+
module.exports = {
14+
meta: {
15+
docs: {
16+
description: 'Disallow broken template',
17+
category: 'Possible Errors',
18+
recommended: true,
19+
},
20+
schema: [],
21+
},
22+
23+
create: function (context) {
24+
return {
25+
TaggedTemplateExpression: function (node) {
26+
if (isReactPugReference(node)) {
27+
const template = getTemplate(node)
28+
29+
try {
30+
findVariablesInTemplate(template)
31+
} catch (error) {
32+
const line = (error.line + node.loc.start.line) - 1
33+
const source = error.src.split('\n')[error.line - 1]
34+
35+
context.report({
36+
node,
37+
loc: buildLocation(
38+
[line, source.replace(/^([\s\t]+).*$/, '$1').length],
39+
[line, source.length],
40+
),
41+
message: 'Pug can\'t parse this template',
42+
})
43+
}
44+
}
45+
},
46+
}
47+
},
48+
}

lib/rules/no-undef.js

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@
33
* @author Eugene Zhlobo
44
*/
55

6-
const { isReactPugReference, getTemplate, extractVariables } = require('../utilities')
6+
const {
7+
isReactPugReference,
8+
getTemplate,
9+
extractVariables,
10+
buildLocation,
11+
} = require('../utilities')
712

813
//------------------------------------------------------------------------------
914
// Rule Definition
@@ -47,16 +52,10 @@ module.exports = {
4752
notDefinedVariables.forEach((variable) => {
4853
context.report({
4954
node,
50-
loc: {
51-
start: {
52-
line: (node.loc.start.line + variable.loc.start.line) - 1,
53-
column: variable.loc.start.column,
54-
},
55-
end: {
56-
line: (node.loc.start.line + variable.loc.end.line) - 1,
57-
column: variable.loc.end.column,
58-
},
59-
},
55+
loc: buildLocation(
56+
[(node.loc.start.line + variable.loc.start.line) - 1, variable.loc.start.column],
57+
[(node.loc.start.line + variable.loc.end.line) - 1, variable.loc.end.column],
58+
),
6059
message: `'${variable.value}' is not defined.`,
6160
})
6261
})

lib/utilities.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,22 @@ function extractVariables(template) {
3939
}
4040
}
4141

42+
function buildLocation(startCoord, endCoord) {
43+
return {
44+
start: {
45+
line: startCoord[0],
46+
column: startCoord[1],
47+
},
48+
end: {
49+
line: endCoord[0],
50+
column: endCoord[1],
51+
},
52+
}
53+
}
54+
4255
module.exports = {
4356
isReactPugReference,
4457
getTemplate,
4558
extractVariables,
59+
buildLocation,
4660
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* @fileoverview Tests for no-broken-template
3+
* @author Eugene Zhlobo
4+
*/
5+
6+
//------------------------------------------------------------------------------
7+
// Requirements
8+
//------------------------------------------------------------------------------
9+
10+
const eslint = require('eslint')
11+
12+
const { RuleTester } = eslint
13+
14+
const rule = require('../../../lib/rules/no-broken-template')
15+
16+
const parserOptions = {
17+
sourceType: 'module',
18+
}
19+
20+
//------------------------------------------------------------------------------
21+
// Tests
22+
//------------------------------------------------------------------------------
23+
24+
const ruleTester = new RuleTester({ parserOptions })
25+
26+
ruleTester.run('rule "no-broken-template"', rule, {
27+
valid: [
28+
{ code: 'pug`p= variable`;' },
29+
{ code: 'pug`Component`;' },
30+
],
31+
invalid: [
32+
{
33+
code: `
34+
/*global pug*/
35+
pug\`
36+
p good string
37+
div
38+
each i in 1, 2, 3]
39+
\`;
40+
`,
41+
errors: [{
42+
line: 6,
43+
column: 13,
44+
endLine: 6,
45+
endColumn: 31,
46+
message: 'Pug can\'t parse this template',
47+
}],
48+
},
49+
],
50+
})

0 commit comments

Comments
 (0)