Skip to content

Commit fd2b964

Browse files
committed
New: the first version.
1 parent e8324cf commit fd2b964

File tree

4 files changed

+176
-0
lines changed

4 files changed

+176
-0
lines changed

index.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* @author Toru Nagashima <https://github.com/mysticatea>
3+
* @copyright 2016 Toru Nagashima. All rights reserved.
4+
* See LICENSE file in root directory for full license.
5+
*/
6+
"use strict"
7+
8+
//------------------------------------------------------------------------------
9+
// Requirements
10+
//------------------------------------------------------------------------------
11+
12+
const espree = require("espree")
13+
const SAXParser = require("parse5").SAXParser
14+
15+
//------------------------------------------------------------------------------
16+
// Helpers
17+
//------------------------------------------------------------------------------
18+
19+
/**
20+
* Extracts the text of the 1st script element in the given text.
21+
*
22+
* @param {string} originalText - The whole text to extract.
23+
* @returns {{text: string, offset: number}} The information of the 1st script.
24+
*/
25+
function extractFirstScript(originalText) {
26+
const parser = new SAXParser({locationInfo: true})
27+
let inScript = false
28+
let text = ""
29+
let offset = 0
30+
31+
parser.on("startTag", (name, attrs, selfClosing) => {
32+
if (name === "script" && !selfClosing) {
33+
inScript = true
34+
}
35+
})
36+
parser.on("endTag", (name) => {
37+
if (name === "script") {
38+
inScript = false
39+
}
40+
})
41+
parser.on("text", (scriptText, location) => {
42+
if (inScript && text === "") {
43+
const lineTerminators = "\n".repeat(location.line - 1)
44+
const spaces = " ".repeat(location.startOffset - location.line + 1)
45+
text = `${spaces}${lineTerminators}${scriptText}`
46+
offset = location.startOffset
47+
}
48+
})
49+
parser.end(originalText)
50+
51+
return {text, offset}
52+
}
53+
54+
//------------------------------------------------------------------------------
55+
// Exports
56+
//------------------------------------------------------------------------------
57+
58+
module.exports.parse = function parse(text, options) {
59+
const script = extractFirstScript(text)
60+
const ast = espree.parse(script.text, options)
61+
62+
ast.start = script.offset
63+
64+
return ast
65+
}

test/fixtures/hello.vue

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<template>
2+
<p>{{ greeting }} World!</p>
3+
</template>
4+
5+
<script>
6+
module.exports = {
7+
data() {
8+
return {greeting: "Hello"}
9+
},
10+
}
11+
</script>
12+
13+
<style scoped>
14+
p {
15+
font-size: 2em;
16+
text-align: center;
17+
}
18+
</style>

test/fixtures/hello.vue.fixed

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<template>
2+
<p>{{ greeting }} World!</p>
3+
</template>
4+
5+
<script>
6+
module.exports = {
7+
data() {
8+
return {greeting: "Hello"};
9+
},
10+
};
11+
</script>
12+
13+
<style scoped>
14+
p {
15+
font-size: 2em;
16+
text-align: center;
17+
}
18+
</style>

test/index.js

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/**
2+
* @author Toru Nagashima <https://github.com/mysticatea>
3+
* @copyright 2016 Toru Nagashima. All rights reserved.
4+
* See LICENSE file in root directory for full license.
5+
*/
6+
"use strict"
7+
8+
//------------------------------------------------------------------------------
9+
// Requirements
10+
//------------------------------------------------------------------------------
11+
12+
const assert = require("assert")
13+
const path = require("path")
14+
const CLIEngine = require("eslint").CLIEngine
15+
const fs = require("fs-extra")
16+
17+
//------------------------------------------------------------------------------
18+
// Helpers
19+
//------------------------------------------------------------------------------
20+
21+
const ORIGINAL_FIXTURE_DIR = path.join(__dirname, "fixtures")
22+
const FIXTURE_DIR = path.join(__dirname, "temp")
23+
const PARSER_PATH = path.resolve(__dirname, "../index.js")
24+
25+
//------------------------------------------------------------------------------
26+
// Tests
27+
//------------------------------------------------------------------------------
28+
29+
describe("About fixtures/hello.vue", () => {
30+
beforeEach(() => {
31+
fs.copySync(ORIGINAL_FIXTURE_DIR, FIXTURE_DIR)
32+
})
33+
afterEach(() => {
34+
fs.removeSync(FIXTURE_DIR)
35+
})
36+
37+
it("should notify 2 'semi' errors", () => {
38+
const cli = new CLIEngine({
39+
cwd: FIXTURE_DIR,
40+
envs: ["es6", "node"],
41+
parser: PARSER_PATH,
42+
rules: {semi: "error"},
43+
useEslintrc: false,
44+
})
45+
const report = cli.executeOnFiles(["hello.vue"])
46+
const messages = report.results[0].messages
47+
48+
assert(messages.length === 2)
49+
assert(messages[0].ruleId === "semi")
50+
assert(messages[0].line === 8)
51+
assert(messages[0].column === 35)
52+
assert(messages[0].source === " return {greeting: \"Hello\"}")
53+
assert(messages[1].ruleId === "semi")
54+
assert(messages[1].line === 10)
55+
assert(messages[1].column === 2)
56+
assert(messages[1].source === "}")
57+
})
58+
59+
it("should fix 2 'semi' errors with --fix option", () => {
60+
const cli = new CLIEngine({
61+
cwd: FIXTURE_DIR,
62+
envs: ["es6", "node"],
63+
fix: true,
64+
parser: PARSER_PATH,
65+
rules: {semi: "error"},
66+
useEslintrc: false,
67+
})
68+
CLIEngine.outputFixes(cli.executeOnFiles(["hello.vue"]))
69+
70+
const actual = fs.readFileSync(path.join(FIXTURE_DIR, "hello.vue"), "utf8")
71+
const expected = fs.readFileSync(path.join(FIXTURE_DIR, "hello.vue.fixed"), "utf8")
72+
73+
assert(actual === expected)
74+
})
75+
})

0 commit comments

Comments
 (0)