diff options
Diffstat (limited to 'sonar-css-plugin/css-bundle/tests')
8 files changed, 273 insertions, 0 deletions
diff --git a/sonar-css-plugin/css-bundle/tests/fixtures/file-bom.css b/sonar-css-plugin/css-bundle/tests/fixtures/file-bom.css new file mode 100644 index 0000000..0ecd9c3 --- /dev/null +++ b/sonar-css-plugin/css-bundle/tests/fixtures/file-bom.css @@ -0,0 +1,2 @@ +p { +} diff --git a/sonar-css-plugin/css-bundle/tests/fixtures/file.css b/sonar-css-plugin/css-bundle/tests/fixtures/file.css new file mode 100644 index 0000000..802e4f0 --- /dev/null +++ b/sonar-css-plugin/css-bundle/tests/fixtures/file.css @@ -0,0 +1 @@ +p { } diff --git a/sonar-css-plugin/css-bundle/tests/fixtures/file.html b/sonar-css-plugin/css-bundle/tests/fixtures/file.html new file mode 100644 index 0000000..02e014f --- /dev/null +++ b/sonar-css-plugin/css-bundle/tests/fixtures/file.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> +<head> + <title>Page Title</title> + <style> +p { +} + </style> +</head> +<body> +</body> +</html> diff --git a/sonar-css-plugin/css-bundle/tests/fixtures/file.php b/sonar-css-plugin/css-bundle/tests/fixtures/file.php new file mode 100644 index 0000000..54d36ee --- /dev/null +++ b/sonar-css-plugin/css-bundle/tests/fixtures/file.php @@ -0,0 +1,13 @@ +<!doctype html> +<html lang="en"> +<head> + <title>Index</title> + <style> + /* S4658 empty block */ + p { } + </style> +</head> +<body> + <?= "Hello World!" ?> +</body> +</html> diff --git a/sonar-css-plugin/css-bundle/tests/fixtures/stylelintconfig.json b/sonar-css-plugin/css-bundle/tests/fixtures/stylelintconfig.json new file mode 100644 index 0000000..44d0932 --- /dev/null +++ b/sonar-css-plugin/css-bundle/tests/fixtures/stylelintconfig.json @@ -0,0 +1,5 @@ +{ + "rules": { + "block-no-empty": true + } +}
\ No newline at end of file diff --git a/sonar-css-plugin/css-bundle/tests/server-mock-stylelint.test.ts b/sonar-css-plugin/css-bundle/tests/server-mock-stylelint.test.ts new file mode 100644 index 0000000..f7df176 --- /dev/null +++ b/sonar-css-plugin/css-bundle/tests/server-mock-stylelint.test.ts @@ -0,0 +1,51 @@ +import { start, setLogHandlersForTests } from "../src/server"; +import { Server } from "http"; +import * as path from "path"; +import { promisify } from "util"; +import * as stylelint from "stylelint"; +import { postToServer } from "./utils"; + +const filePath = path.join(__dirname, "fixtures", "file.css"); + +const request = JSON.stringify({ + filePath, + configFile: path.join(__dirname, "fixtures", "stylelintconfig.json") +}); + +jest.mock("stylelint"); + +describe("server", () => { + let server: Server; + let close: () => Promise<void>; + const logSpy = jest.fn(); + const errorSpy = jest.fn(); + + beforeAll(async () => { + setLogHandlersForTests(logSpy, errorSpy); + server = await start(); + close = promisify(server.close.bind(server)); + }); + + afterAll(async () => { + jest.restoreAllMocks(); + await close(); + }); + + it("should not return issues for not original file", async () => { + (stylelint.lint as any).mockResolvedValue({ + results: [{ source: "foo.bar" }] + }); + const response = await postToServer(request, "/analyze", server); + expect(JSON.parse(response)).toEqual([]); + expect(logSpy).toHaveBeenCalledWith( + `DEBUG For file [${filePath}] received issues with [foo.bar] as a source. They will not be reported.` + ); + }); + + it("should not return issues when failed promise returned", async () => { + (stylelint.lint as any).mockRejectedValue("some reason"); + const response = await postToServer(request, "/analyze", server); + expect(JSON.parse(response)).toEqual([]); + expect(errorSpy).toHaveBeenCalledWith("some reason"); + }); +}); diff --git a/sonar-css-plugin/css-bundle/tests/server.test.ts b/sonar-css-plugin/css-bundle/tests/server.test.ts new file mode 100644 index 0000000..8465810 --- /dev/null +++ b/sonar-css-plugin/css-bundle/tests/server.test.ts @@ -0,0 +1,153 @@ +import { start, setLogHandlersForTests } from "../src/server"; +import * as http from "http"; +import { Server } from "http"; +import { promisify } from "util"; +import { AddressInfo } from "net"; +import { postToServer } from "./utils"; +import * as path from "path"; + +const configFile = path.join(__dirname, "fixtures", "stylelintconfig.json"); + +describe("server", () => { + let server: Server; + let close: () => Promise<void>; + const logSpy = jest.fn(); + const errorSpy = jest.fn(); + + beforeAll(async () => { + setLogHandlersForTests(logSpy, errorSpy); + server = await start(); + close = promisify(server.close.bind(server)); + }); + + afterAll(async () => { + jest.restoreAllMocks(); + await close(); + }); + + it("should log with debug server start", async () => { + expect(server.listening).toEqual(true); + expect(logSpy).toBeCalledTimes(2); + expect(logSpy).toBeCalledWith( + "DEBUG starting stylelint-bridge server at port", + 0 + ); + expect(logSpy).toBeCalledWith( + "DEBUG stylelint-bridge server is running at port", + (<AddressInfo>server.address()).port + ); + expect(errorSpy).toBeCalledTimes(0); + }); + + it("should respond to analysis request", async () => { + const request = JSON.stringify({ + filePath: path.join(__dirname, "fixtures", "file.css"), + configFile + }); + const response = await post(request, "/analyze"); + expect(JSON.parse(response)).toEqual([ + { + line: 1, + rule: "block-no-empty", + text: "Unexpected empty block (block-no-empty)" + } + ]); + }); + + it("should respond to analysis request for php", async () => { + const requestPhp = JSON.stringify({ + filePath: path.join(__dirname, "fixtures", "file.php"), + configFile + }); + const responsePhp = await post(requestPhp, "/analyze"); + expect(JSON.parse(responsePhp)).toEqual([ + { + line: 7, + rule: "block-no-empty", + text: "Unexpected empty block (block-no-empty)" + } + ]); + }); + + it("should respond to analysis request for html", async () => { + const requestHtml = JSON.stringify({ + filePath: path.join(__dirname, "fixtures", "file.html"), + configFile + }); + const responseHtml = await post(requestHtml, "/analyze"); + expect(JSON.parse(responseHtml)).toEqual([ + { + line: 6, + rule: "block-no-empty", + text: "Unexpected empty block (block-no-empty)" + } + ]); + }); + + it("should cut BOM", async () => { + const response = await post( + JSON.stringify({ + filePath: path.join(__dirname, "fixtures", "file-bom.css"), + configFile + }), + "/analyze" + ); + expect(JSON.parse(response)).toEqual([ + { + line: 1, + rule: "block-no-empty", + text: "Unexpected empty block (block-no-empty)" + } + ]); + }); + + it("should respond OK! when started", done => { + const req = http.request( + { + host: "localhost", + port: (<AddressInfo>server.address()).port, + path: "/status", + method: "GET" + }, + res => { + let data = ""; + res.on("data", chunk => { + data += chunk; + }); + res.on("end", () => { + expect(data).toEqual("OK!"); + done(); + }); + } + ); + req.end(); + }); + + it("should return empty list of issues when request not json", async () => { + const response = await post("invalid json", "/analyze"); + expect(JSON.parse(response)).toEqual([]); + expect(errorSpy).toHaveBeenCalledWith( + expect.objectContaining({ + message: expect.stringContaining( + "Unexpected token i in JSON at position 0" + ) + }) + ); + }); + + it("should return empty list of issues when invalid request", async () => { + const response = await post("{}", "/analyze"); + expect(JSON.parse(response)).toEqual([]); + expect(errorSpy).toHaveBeenCalledWith( + expect.objectContaining({ + message: expect.stringContaining( + "Unexpected token i in JSON at position 0" + ) + }) + ); + }); + + function post(data: string, endpoint: string): Promise<string> { + return postToServer(data, endpoint, server); + } +}); diff --git a/sonar-css-plugin/css-bundle/tests/utils.ts b/sonar-css-plugin/css-bundle/tests/utils.ts new file mode 100644 index 0000000..0be132b --- /dev/null +++ b/sonar-css-plugin/css-bundle/tests/utils.ts @@ -0,0 +1,36 @@ +import * as http from "http"; +import { Server } from "http"; +import { AddressInfo } from "net"; + +export function postToServer( + data: string, + endpoint: string, + server: Server +): Promise<string> { + const options = { + host: "localhost", + port: (<AddressInfo>server.address()).port, + path: endpoint, + method: "POST", + headers: { + "Content-Type": "application/json" + } + }; + + return new Promise((resolve, reject) => { + let response = ""; + + const req = http.request(options, res => { + res.on("data", chunk => { + response += chunk; + }); + + res.on("end", () => resolve(response)); + }); + + req.on("error", reject); + + req.write(data); + req.end(); + }); +} |
