Skip to content

Commit 46662bd

Browse files
committed
test: integ tests for eslint on jsx files
1 parent b5275d8 commit 46662bd

File tree

9 files changed

+174
-4
lines changed

9 files changed

+174
-4
lines changed

.eslintignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@ test/temp/**
2222
test/thirdparty/**
2323
test/**/node_modules/**/*.js
2424
test/virtual-server-test.js
25-
25+
test/spec/ESLintExtensionTest-files
2626

src-node/ESLint/runner.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,16 @@ async function getESLinter() {
6767
// when caching, make sure that a new eslint object is created when any of the eslint config file changes!!!.
6868
}
6969

70+
async function _getConfigDetails(eslinter, filePath) {
71+
try{
72+
const config = await eslinter.calculateConfigForFile(filePath);
73+
return JSON.parse(JSON.stringify(config)); // ensure that this is stringify able
74+
} catch (e) {
75+
console.error("Failed to compute config", e);
76+
return null;
77+
}
78+
}
79+
7080
async function lintTextWithPath(text, fullFilePath) {
7181
// Create an ESLint instance
7282
const eslinter = await getESLinter();
@@ -94,7 +104,8 @@ async function lintTextWithPath(text, fullFilePath) {
94104
// Return the results as an array
95105
delete result.source;
96106
return {
97-
result
107+
result,
108+
config: await _getConfigDetails(eslinter, fullFilePath)
98109
};
99110
}
100111

src/extensions/default/JSLint/ESLint.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ define(function (require, exports, module) {
3838
StringUtils = brackets.getModule("utils/StringUtils"),
3939
ProjectManager = brackets.getModule("project/ProjectManager"),
4040
FileSystem = brackets.getModule("filesystem/FileSystem"),
41+
LanguageManager = brackets.getModule("language/LanguageManager"),
4142
NodeUtils = brackets.getModule("utils/NodeUtils");
4243

4344
let prefs = PreferencesManager.getExtensionPrefs("ESLint"),
@@ -125,6 +126,18 @@ define(function (require, exports, module) {
125126
});
126127
}
127128

129+
function _isEslintSupportsJSX(config) {
130+
if(!config){
131+
return false;
132+
}
133+
let parserOptions = config.parserOptions; // es 7, 8
134+
if(!parserOptions && config.languageOptions && config.languageOptions.parserOptions){
135+
// this is for es9 and later
136+
parserOptions = config.languageOptions.parserOptions;
137+
}
138+
return parserOptions && parserOptions.ecmaFeatures && parserOptions.ecmaFeatures.jsx;
139+
}
140+
128141
/**
129142
* Run JSLint on the current document. Reports results to the main UI. Displays
130143
* a gold star when no errors are found.
@@ -136,7 +149,10 @@ define(function (require, exports, module) {
136149
return;
137150
}
138151
NodeUtils.ESLintFile(text, fullPath, ProjectManager.getProjectRoot().fullPath).then(esLintResult =>{
139-
if (esLintResult.result && esLintResult.result.messages && esLintResult.result.messages.length) {
152+
const language = LanguageManager.getLanguageForPath(fullPath).getId();
153+
if(language === "jsx" && !_isEslintSupportsJSX(esLintResult.config)){
154+
resolve({isIgnored: true});
155+
} else if (esLintResult.result && esLintResult.result.messages && esLintResult.result.messages.length) {
140156
esLintServiceFailed = false;
141157
resolve({ errors: _getErrors(esLintResult.result.messages) });
142158
} else if(esLintResult.isError) {

test/spec/CodeInspection-integ-test.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,6 +1108,48 @@ define(function (require, exports, module) {
11081108
expect(fixPos(EditorManager.getActiveEditor().getCursorPos())).toEqual(fixPos({line: 1, ch: 3}));
11091109
});
11101110

1111+
it("should not show providers that returns isIgnored", async function () {
1112+
var codeInspector1 = createCodeInspector("javascript linter x", {
1113+
isIgnored: true
1114+
});
1115+
const linterName = "javascript linter y";
1116+
var codeInspector2 = createCodeInspector(linterName, {
1117+
errors: [
1118+
{
1119+
pos: { line: 0, ch: 2 },
1120+
message: "Different error",
1121+
type: CodeInspection.Type.WARNING
1122+
}
1123+
]
1124+
});
1125+
CodeInspection.register("javascript", codeInspector1);
1126+
CodeInspection.register("javascript", codeInspector2);
1127+
1128+
await awaitsForDone(SpecRunnerUtils.openProjectFiles(["errors.js"]), "open test file");
1129+
1130+
const $problemPanelTitle = $("#problems-panel .title").text();
1131+
expect($problemPanelTitle).toBe(StringUtils.format(Strings.SINGLE_ERROR, linterName, "errors.js"));
1132+
1133+
var $statusBar = $("#status-inspection");
1134+
expect($statusBar.is(":visible")).toBe(true);
1135+
});
1136+
1137+
it("should not show no error if all isIgnored", async function () {
1138+
var codeInspector1 = createCodeInspector("javascript linter x", {
1139+
isIgnored: true
1140+
});
1141+
const linterName = "javascript linter y";
1142+
var codeInspector2 = createCodeInspector(linterName, {
1143+
isIgnored: true
1144+
});
1145+
CodeInspection.register("javascript", codeInspector1);
1146+
CodeInspection.register("javascript", codeInspector2);
1147+
1148+
await awaitsForDone(SpecRunnerUtils.openProjectFiles(["errors.js"]), "open test file");
1149+
1150+
expect($("#status-inspection").hasClass("inspection-disabled")).toBeTrue();
1151+
});
1152+
11111153
it("should handle missing or negative line numbers gracefully (https://github.com/adobe/brackets/issues/6441)", async function () {
11121154
var codeInspector1 = createCodeInspector("NoLineNumberLinter", {
11131155
errors: [
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
function formatName(user) {
2+
return user.firstName + ' ' + user.lastName;
3+
}
4+
5+
const user = {
6+
firstName: 'Harper',
7+
lastName: 'Perez'
8+
};
9+
10+
const element = (
11+
<h1 id="dd">
12+
Hello, {formatName(user)}!
13+
</h1>
14+
);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"env": {
3+
"browser": true,
4+
"es2021": true
5+
},
6+
"extends": [
7+
"eslint:recommended",
8+
"plugin:react/recommended"
9+
],
10+
"parserOptions": {
11+
"ecmaFeatures": {
12+
"jsx": true
13+
},
14+
"ecmaVersion": 12,
15+
"sourceType": "module"
16+
},
17+
"plugins": [
18+
"react"
19+
],
20+
"rules": {
21+
"react/react-in-jsx-scope": "off"
22+
},
23+
"settings": {
24+
"react": {
25+
"version": "detect"
26+
}
27+
}
28+
}
29+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name": "misc",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "index.js",
6+
"type": "module",
7+
"scripts": {},
8+
"author": "",
9+
"license": "ISC",
10+
"devDependencies": {
11+
"eslint": "^8.57.0",
12+
"eslint-plugin-react": "^7.34.2",
13+
"eslint-plugin-react-hooks": "^4.6.2"
14+
}
15+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
function formatName(user) {
2+
return user.firstName + ' ' + user.lastName;
3+
}
4+
5+
const user = {
6+
firstName: 'Harper',
7+
lastName: 'Perez'
8+
};
9+
10+
const element = (
11+
<h1 id="dd">
12+
Hello, {formatName(user)}!
13+
</h1>
14+
);

test/spec/Extn-ESLint-integ-test.js

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ define(function (require, exports, module) {
6868

6969
const JSHintErrorES6Error_js = "Missing semicolon. jshint (W033)",
7070
ESLintErrorES7Error_js = "Parsing error: Unexpected token ; ESLint (null)",
71-
ESLintErrorES8Error_js = "Expected '===' and instead saw '=='. ESLint (eqeqeq)";
71+
ESLintErrorES8Error_js = "Expected '===' and instead saw '=='. ESLint (eqeqeq)",
72+
ESLintReactError_js = "'element' is assigned a value but never used. ESLint (no-unused-vars)";
7273

7374
async function _createTempProject(esLintSpecSubFolder) {
7475
return await SpecRunnerUtils.getTempTestDirectory(testRootSpec + esLintSpecSubFolder);
@@ -204,6 +205,27 @@ define(function (require, exports, module) {
204205
}, 5000);
205206
});
206207

208+
describe("ES8 with react js support project", function () { // this should cover es7 too
209+
let reactProjectPath;
210+
211+
beforeAll(async function () {
212+
reactProjectPath = await _createTempProject("es8_react_jsx");
213+
await _npmInstallInFolder(reactProjectPath);
214+
await SpecRunnerUtils.loadProjectInTestWindow(reactProjectPath);
215+
}, 30000);
216+
217+
it("should ESLint jsx reactjs in v8 work as expected", async function () {
218+
await _openProjectFile("react.jsx");
219+
await _waitForProblemsPanelVisible(true);
220+
await awaitsFor(()=>{
221+
return $("#problems-panel").text().includes(ESLintReactError_js);
222+
}, "ESLint jsx error to be shown");
223+
}, 5000);
224+
});
225+
226+
// we should have an es9 test too as above, but es9 currently doesnt support jsx
227+
// https://github.com/facebook/react/pull/28773 do when available.
228+
207229
describe("ES8 module project", function () {
208230
let es7ProjectPath;
209231

@@ -225,6 +247,13 @@ define(function (require, exports, module) {
225247
await _loadAndValidateES8Project();
226248
}, 5000);
227249

250+
it("should not lint jsx file as ESLint v8 is not configured for react lint", async function () {
251+
await _openProjectFile("react.jsx");
252+
await awaits(100); // Just wait for some time to prevent any false linter runs
253+
await _waitForProblemsPanelVisible(false);
254+
expect($("#status-inspection").hasClass("inspection-disabled")).toBeTrue();
255+
}, 5000);
256+
228257
it("should not show JSHint in desktop app if ESLint is active", async function () {
229258
await _loadAndValidateES8Project();
230259
await awaits(100); // give some time so that jshint has time to complete if there is any.

0 commit comments

Comments
 (0)