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(); +  }); +} | 
