diff --git a/.eslintrc.json b/.eslintrc.json index 14d1eb00b4..bfe91b2d11 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -19,17 +19,22 @@ "@typescript-eslint/no-parameter-properties": ["off"], "@typescript-eslint/no-unused-vars": [ "error", - { "argsIgnorePattern": "^_" } + { "argsIgnorePattern": "^_", "varsIgnorePattern": "^_" } ], "@typescript-eslint/ban-ts-ignore": ["off"], - "@typescript-eslint/no-empty-function": ["off"], - "@typescript-eslint/explicit-function-return-type": ["off"] + "@typescript-eslint/no-empty-function": ["off"] }, "overrides": [ { - "files": ["*.ts", "*.tsx"], + "files": ["*.js"], "rules": { - "@typescript-eslint/explicit-function-return-type": ["error"] + "@typescript-eslint/explicit-function-return-type": ["off"] + } + }, + { + "files": ["tools/node_*.js"], + "rules": { + "@typescript-eslint/no-var-requires": ["off"] } } ] diff --git a/.prettierignore b/.prettierignore index 9d83dd750e..695354438c 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,2 @@ -js/flatbuffers.js tests/error_syntax.js tests/badly_formatted.js diff --git a/tools/complex_permissions_test.py b/tools/complex_permissions_test.py index 32385649ba..cc35577ded 100755 --- a/tools/complex_permissions_test.py +++ b/tools/complex_permissions_test.py @@ -106,7 +106,7 @@ class TestWritePermissions(BaseReadWritePermissionsTest, class TestNetFetchPermissions(BaseComplexPermissionTest): - test_type = "net_fetch" + test_type = "netFetch" def test_allow_localhost_4545(self): code, _stdout, stderr = self._run_deno( @@ -143,7 +143,7 @@ class TestNetFetchPermissions(BaseComplexPermissionTest): class TestNetDialPermissions(BaseComplexPermissionTest): - test_type = "net_dial" + test_type = "netDial" def test_allow_localhost_ip_4555(self): code, _stdout, stderr = self._run_deno( @@ -177,7 +177,7 @@ class TestNetDialPermissions(BaseComplexPermissionTest): class TestNetListenPermissions(BaseComplexPermissionTest): - test_type = "net_listen" + test_type = "netListen" def test_allow_localhost_4555(self): code, _stdout, stderr = self._run_deno( diff --git a/tools/complex_permissions_test.ts b/tools/complex_permissions_test.ts index b0e13b6e58..dd65a0e330 100644 --- a/tools/complex_permissions_test.ts +++ b/tools/complex_permissions_test.ts @@ -1,28 +1,26 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -const { args, readFileSync, writeFileSync, exit, dial } = Deno; +const { args, readFileSync, writeFileSync, exit } = Deno; const name = args[1]; const test: (args: string[]) => void = { - read: (files: string[]): void => { - files.forEach((file): any => readFileSync(file)); + read(files: string[]): void { + files.forEach(file => readFileSync(file)); }, - write: (files: string[]): void => { - files.forEach( - (file): any => writeFileSync(file, new Uint8Array(), { append: true }) + write(files: string[]): void { + files.forEach(file => + writeFileSync(file, new Uint8Array(0), { append: true }) ); }, - net_fetch: (hosts: string[]): void => { - hosts.forEach((host): any => fetch(host)); + netFetch(hosts: string[]): void { + hosts.forEach(host => fetch(host)); }, - net_listen: (hosts: string[]): void => { - hosts.forEach( - (host): any => { - const listener = Deno.listen("tcp", host); - listener.close(); - } - ); + netListen(hosts: string[]): void { + hosts.forEach(host => { + const listener = Deno.listen("tcp", host); + listener.close(); + }); }, - net_dial: async (hosts: string[]): Promise => { + async netDial(hosts: string[]): Promise { for (const host of hosts) { const listener = await Deno.dial("tcp", host); listener.close(); diff --git a/tools/deno_http_proxy.ts b/tools/deno_http_proxy.ts index 0b775ad075..d7a5dda2d0 100644 --- a/tools/deno_http_proxy.ts +++ b/tools/deno_http_proxy.ts @@ -15,7 +15,7 @@ async function main(): Promise { } } -async function proxyRequest(req: ServerRequest) { +async function proxyRequest(req: ServerRequest): Promise { const url = `http://${originAddr}${req.url}`; const resp = await fetch(url, { method: req.method, diff --git a/tools/lint.py b/tools/lint.py index 61c6c59cea..e71d5d0efe 100755 --- a/tools/lint.py +++ b/tools/lint.py @@ -38,12 +38,8 @@ def eslint(): print "eslint" script = os.path.join(third_party_path, "node_modules", "eslint", "bin", "eslint") - # TODO: Files in 'deno_typescript', 'tools' and 'website' directories are - # currently not linted, but they should. - source_files = git_ls_files( - root_path, - ["*.js", "*.ts", ":!:deno_typescript/", ":!:tools/", ":!:website/"]) # Find all *directories* in the main repo that contain .ts/.js files. + source_files = git_ls_files(root_path, ["*.js", "*.ts"]) source_dirs = set([os.path.dirname(f) for f in source_files]) # Within the source dirs, eslint does its own globbing, taking into account # the exclusion rules listed in '.eslintignore'. diff --git a/tools/node_tcp_promise.js b/tools/node_tcp_promise.js index c8fc54aba9..c6de120b1d 100644 --- a/tools/node_tcp_promise.js +++ b/tools/node_tcp_promise.js @@ -9,7 +9,7 @@ const response = Buffer.from( ); async function write(socket, buffer) { - let p = new Promise((resolve, reject) => { + const p = new Promise((resolve, _) => { socket.write(buffer, resolve); }); return p; @@ -19,7 +19,7 @@ Server(async socket => { socket.on("error", _ => { socket.destroy(); }); - for await (const data of socket) { + for await (const _ of socket) { write(socket, response); } }).listen(port); diff --git a/tools/permission_prompt_test.ts b/tools/permission_prompt_test.ts index a4c9e43626..617f8b0fcb 100644 --- a/tools/permission_prompt_test.ts +++ b/tools/permission_prompt_test.ts @@ -5,7 +5,7 @@ const firstCheckFailedMessage = "First check failed"; const name = args[1]; const test = { - needsRead: async () => { + async needsRead(): Promise { try { readFileSync("package.json"); } catch (e) { @@ -13,7 +13,7 @@ const test = { } readFileSync("package.json"); }, - needsWrite: () => { + needsWrite(): void { try { makeTempDirSync(); } catch (e) { @@ -21,7 +21,7 @@ const test = { } makeTempDirSync(); }, - needsEnv: () => { + needsEnv(): void { try { env().home; } catch (e) { @@ -29,7 +29,7 @@ const test = { } env().home; }, - needsNet: () => { + needsNet(): void { try { listen("tcp", "127.0.0.1:4540"); } catch (e) { @@ -37,9 +37,9 @@ const test = { } listen("tcp", "127.0.0.1:4541"); }, - needsRun: () => { + needsRun(): void { try { - const process = run({ + run({ args: [ "python", "-c", @@ -49,7 +49,7 @@ const test = { } catch (e) { console.log(firstCheckFailedMessage); } - const process = run({ + run({ args: [ "python", "-c", diff --git a/website/app.ts b/website/app.ts index c22c0d2c2d..809be51bb4 100644 --- a/website/app.ts +++ b/website/app.ts @@ -3,17 +3,71 @@ // How much to multiply time values in order to process log graphs properly. const TimeScaleFactor = 10000; -export async function getJson(path) { +export interface BenchmarkExecTimeResult { + min?: number; + max?: number; + mean?: number; + stddev?: number; + system?: number; + user?: number; +} + +export interface BenchmarkExecTimeResultSet { + [variant: string]: BenchmarkExecTimeResult; +} + +export interface BenchmarkVariantsResultSet { + [variant: string]: number; +} + +export interface BenchmarkRun { + created_at: string; + sha1: string; + benchmark: BenchmarkExecTimeResultSet; + binary_size?: BenchmarkVariantsResultSet | number; + max_memory?: BenchmarkVariantsResultSet | number; + bundle_size?: BenchmarkVariantsResultSet; + max_latency?: BenchmarkVariantsResultSet; + req_per_sec?: BenchmarkVariantsResultSet; + req_per_sec_proxy?: BenchmarkVariantsResultSet; + syscall_count?: BenchmarkVariantsResultSet; + thread_count?: BenchmarkVariantsResultSet; + throughput?: BenchmarkVariantsResultSet; +} + +export type BenchmarkName = Exclude; + +type Column = [string, ...Array]; + +interface C3DataNode { + id: string; + index: number; + name: string; + value: number; + x: number; +} + +type C3OnClickCallback = (C3DataNode, unknown) => void; +type C3OnRenderedCallback = () => void; +type C3TickFormatter = (number) => number | string; + +export async function getJson(path: string): Promise { return (await fetch(path)).json(); } -function getBenchmarkVarieties(data, benchmarkName) { +function getBenchmarkVarieties( + data: BenchmarkRun[], + benchmarkName: BenchmarkName +): string[] { // Look at last sha hash. const last = data[data.length - 1]; return Object.keys(last[benchmarkName]); } -export function createColumns(data, benchmarkName) { +export function createColumns( + data: BenchmarkRun[], + benchmarkName: BenchmarkName +): Column[] { const varieties = getBenchmarkVarieties(data, benchmarkName); return varieties.map(variety => [ variety, @@ -35,11 +89,11 @@ export function createColumns(data, benchmarkName) { } export function createNormalizedColumns( - data, - benchmarkName, - baselineBenchmark, - baselineVariety -) { + data: BenchmarkRun[], + benchmarkName: BenchmarkName, + baselineBenchmark: BenchmarkName, + baselineVariety: string +): Column[] { const varieties = getBenchmarkVarieties(data, benchmarkName); return varieties.map(variety => [ variety, @@ -65,19 +119,19 @@ export function createNormalizedColumns( ]); } -export function createExecTimeColumns(data) { +export function createExecTimeColumns(data: BenchmarkRun[]): Column[] { return createColumns(data, "benchmark"); } -export function createThroughputColumns(data) { +export function createThroughputColumns(data: BenchmarkRun[]): Column[] { return createColumns(data, "throughput"); } -export function createProxyColumns(data) { +export function createProxyColumns(data: BenchmarkRun[]): Column[] { return createColumns(data, "req_per_sec_proxy"); } -export function createNormalizedProxyColumns(data) { +export function createNormalizedProxyColumns(data: BenchmarkRun[]): Column[] { return createNormalizedColumns( data, "req_per_sec_proxy", @@ -86,23 +140,25 @@ export function createNormalizedProxyColumns(data) { ); } -export function createReqPerSecColumns(data) { +export function createReqPerSecColumns(data: BenchmarkRun[]): Column[] { return createColumns(data, "req_per_sec"); } -export function createNormalizedReqPerSecColumns(data) { +export function createNormalizedReqPerSecColumns( + data: BenchmarkRun[] +): Column[] { return createNormalizedColumns(data, "req_per_sec", "req_per_sec", "hyper"); } -export function createMaxLatencyColumns(data) { +export function createMaxLatencyColumns(data: BenchmarkRun[]): Column[] { return createColumns(data, "max_latency"); } -export function createMaxMemoryColumns(data) { +export function createMaxMemoryColumns(data: BenchmarkRun[]): Column[] { return createColumns(data, "max_memory"); } -export function createBinarySizeColumns(data) { +export function createBinarySizeColumns(data: BenchmarkRun[]): Column[] { const propName = "binary_size"; const binarySizeNames = Object.keys(data[data.length - 1][propName]); return binarySizeNames.map(name => [ @@ -122,7 +178,7 @@ export function createBinarySizeColumns(data) { ]); } -export function createThreadCountColumns(data) { +export function createThreadCountColumns(data: BenchmarkRun[]): Column[] { const propName = "thread_count"; const threadCountNames = Object.keys(data[data.length - 1][propName]); return threadCountNames.map(name => [ @@ -137,7 +193,7 @@ export function createThreadCountColumns(data) { ]); } -export function createSyscallCountColumns(data) { +export function createSyscallCountColumns(data: BenchmarkRun[]): Column[] { const propName = "syscall_count"; const syscallCountNames = Object.keys(data[data.length - 1][propName]); return syscallCountNames.map(name => [ @@ -152,27 +208,27 @@ export function createSyscallCountColumns(data) { ]); } -export function createBundleSizeColumns(data) { +export function createBundleSizeColumns(data: BenchmarkRun[]): Column[] { return createColumns(data, "bundle_size"); } -export function createSha1List(data) { +export function createSha1List(data: BenchmarkRun[]): string[] { return data.map(d => d.sha1); } -export function formatKB(bytes) { +export function formatKB(bytes: number): string { return (bytes / 1024).toFixed(2); } -export function formatMB(bytes) { +export function formatMB(bytes: number): string { return (bytes / (1024 * 1024)).toFixed(2); } -export function formatReqSec(reqPerSec) { - return reqPerSec / 1000; +export function formatReqSec(reqPerSec: number): string { + return (reqPerSec / 1000).toFixed(3); } -export function formatPercentage(decimal) { +export function formatPercentage(decimal: number): string { return (decimal * 100).toFixed(2); } @@ -186,15 +242,15 @@ export function formatPercentage(decimal) { * @param {boolean} zoomEnabled enables the zoom feature */ function generate( - id, - categories, - columns, - onclick, + id: string, + categories: string[], + columns: Column[], + onclick: C3OnClickCallback, yLabel = "", - yTickFormat = null, + yTickFormat?: C3TickFormatter, zoomEnabled = true, - onrendered = () => {} -) { + onrendered?: C3OnRenderedCallback +): void { const yAxis = { padding: { bottom: 0 }, min: 0, @@ -207,12 +263,12 @@ function generate( }; if (yTickFormat == logScale) { delete yAxis.min; - for (let col of columns) { + for (const col of columns) { for (let i = 1; i < col.length; i++) { if (col[i] == null || col[i] === 0) { continue; } - col[i] = Math.log10(col[i] * TimeScaleFactor); + col[i] = Math.log10((col[i] as number) * TimeScaleFactor); } } } @@ -240,21 +296,14 @@ function generate( }); } -function logScale(t) { +function logScale(t: number): string { return (Math.pow(10, t) / TimeScaleFactor).toFixed(4); } -function formatSecsAsMins(t) { - // TODO use d3.round() - const a = t % 60; - const min = Math.floor(t / 60); - return a < 30 ? min : min + 1; -} - /** * @param dataUrl The url of benchmark data json. */ -export function drawCharts(dataUrl) { +export function drawCharts(dataUrl: string): Promise { // TODO Using window["location"]["hostname"] instead of // window.location.hostname because when deno runs app_test.js it gets a type // error here, not knowing about window.location. Ideally Deno would skip @@ -265,11 +314,8 @@ export function drawCharts(dataUrl) { return drawChartsFromBenchmarkData(dataUrl); } -const proxyFields = [ - "req_per_sec" - //"max_latency" -]; -function extractProxyFields(data) { +const proxyFields: BenchmarkName[] = ["req_per_sec"]; +function extractProxyFields(data: BenchmarkRun[]): void { for (const row of data) { for (const field of proxyFields) { const d = row[field]; @@ -290,8 +336,10 @@ function extractProxyFields(data) { /** * Draws the charts from the benchmark data stored in gh-pages branch. */ -export async function drawChartsFromBenchmarkData(dataUrl) { - const data = await getJson(dataUrl); +export async function drawChartsFromBenchmarkData( + dataUrl: string +): Promise { + const data = (await getJson(dataUrl)) as BenchmarkRun[]; // hack to extract proxy fields from req/s fields extractProxyFields(data); @@ -311,25 +359,23 @@ export async function drawChartsFromBenchmarkData(dataUrl) { const sha1List = createSha1List(data); const sha1ShortList = sha1List.map(sha1 => sha1.substring(0, 6)); - const viewCommitOnClick = _sha1List => d => { + function viewCommitOnClick(d: C3DataNode, _: unknown): void { // @ts-ignore - window.open( - `https://github.com/denoland/deno/commit/${_sha1List[d["index"]]}` - ); - }; + window.open(`https://github.com/denoland/deno/commit/${sha1List[d.index]}`); + } function gen( - id, - columns, + id: string, + columns: Column[], yLabel = "", - yTickFormat = null, - onrendered = () => {} - ) { + yTickFormat?: C3TickFormatter, + onrendered?: C3OnRenderedCallback + ): void { generate( id, sha1ShortList, columns, - viewCommitOnClick(sha1List), + viewCommitOnClick, yLabel, yTickFormat, true, @@ -363,8 +409,8 @@ export async function drawChartsFromBenchmarkData(dataUrl) { gen("#bundle-size-chart", bundleSizeColumns, "kilobytes", formatKB); } -function hideOnRender(elementID) { - return () => { +function hideOnRender(elementID: string): C3OnRenderedCallback { + return (): void => { const chart = window["document"].getElementById(elementID); if (!chart.getAttribute("data-inital-hide-done")) { chart.setAttribute("data-inital-hide-done", "true"); @@ -373,12 +419,16 @@ function hideOnRender(elementID) { }; } -function registerNormalizedSwitcher(checkboxID, chartID, normalizedChartID) { +function registerNormalizedSwitcher( + checkboxID: string, + chartID: string, + normalizedChartID: string +): void { const checkbox = window["document"].getElementById(checkboxID); const regularChart = window["document"].getElementById(chartID); const normalizedChart = window["document"].getElementById(normalizedChartID); - checkbox.addEventListener("change", event => { + checkbox.addEventListener("change", _ => { // If checked is true the normalized variant should be shown // @ts-ignore if (checkbox.checked) { @@ -395,15 +445,15 @@ export function main(): void { window["chartWidth"] = 800; const overlay = window["document"].getElementById("spinner-overlay"); - function showSpinner() { + function showSpinner(): void { overlay.style.display = "block"; } - function hideSpinner() { + function hideSpinner(): void { overlay.style.display = "none"; } - function updateCharts() { + function updateCharts(): void { const u = window.location.hash.match("all") ? "./data.json" : "recent.json"; showSpinner(); diff --git a/website/app_test.ts b/website/app_test.ts index c16487585f..cae3a989bf 100644 --- a/website/app_test.ts +++ b/website/app_test.ts @@ -1,8 +1,9 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { test, testPerm, assert, assertEquals } from "../js/test_util.ts"; +import { test, assertEquals } from "../js/test_util.ts"; import { runIfMain } from "../js/deps/https/deno.land/std/testing/mod.ts"; import { + BenchmarkRun, createBinarySizeColumns, createExecTimeColumns, createThreadCountColumns, @@ -10,7 +11,8 @@ import { createSha1List } from "./app.ts"; -const regularData = [ +/* eslint-disable @typescript-eslint/camelcase */ +const regularData: BenchmarkRun[] = [ { created_at: "2018-01-01T01:00:00Z", sha1: "abcdef", @@ -97,7 +99,7 @@ const regularData = [ } ]; -const irregularData = [ +const irregularData: BenchmarkRun[] = [ { created_at: "2018-01-01T01:00:00Z", sha1: "123", @@ -132,6 +134,7 @@ const irregularData = [ } } ]; +/* eslint-enable @typescript-eslint/camelcase */ test(function createExecTimeColumnsRegularData() { const columns = createExecTimeColumns(regularData); diff --git a/website/showdown_toc.js b/website/showdown_toc.js index ba1f65c719..886036443d 100644 --- a/website/showdown_toc.js +++ b/website/showdown_toc.js @@ -25,13 +25,14 @@ } function getHeaderEntriesInNodeJs(sourceHtml) { - var cheerio = require("cheerio"); - var $ = cheerio.load(sourceHtml); - var headers = $("h1, h2, h3, h4, h5, h6"); + // eslint-disable-next-line @typescript-eslint/no-var-requires + const cheerio = require("cheerio"); + const $ = cheerio.load(sourceHtml); + const headers = $("h1, h2, h3, h4, h5, h6"); - var headerList = []; - for (var i = 0; i < headers.length; i++) { - var el = headers[i]; + const headerList = []; + for (let i = 0; i < headers.length; i++) { + const el = headers[i]; headerList.push(new TocEntry(el.name, $(el).text(), $(el).attr("id"))); } @@ -40,14 +41,14 @@ function getHeaderEntriesInBrowser(sourceHtml) { // Generate dummy element - var source = document.createElement("div"); + const source = document.createElement("div"); source.innerHTML = sourceHtml; // Find headers - var headers = source.querySelectorAll("h1, h2, h3, h4, h5, h6"); - var headerList = []; - for (var i = 0; i < headers.length; i++) { - var el = headers[i]; + const headers = source.querySelectorAll("h1, h2, h3, h4, h5, h6"); + const headerList = []; + for (let i = 0; i < headers.length; i++) { + const el = headers[i]; headerList.push(new TocEntry(el.tagName, el.textContent, el.id)); } @@ -65,8 +66,8 @@ if (this.children.length === 0) { return ""; } - var result = "
    \n"; - for (var i = 0; i < this.children.length; i++) { + let result = "
      \n"; + for (let i = 0; i < this.children.length; i++) { result += this.children[i].toString(); } result += "
    \n"; @@ -74,7 +75,7 @@ }; TocEntry.prototype.toString = function() { - var result = "
  • "; + let result = "
  • "; if (this.text) { result += '' + this.text + ""; } @@ -85,9 +86,8 @@ function sortHeader(tocEntries, level) { level = level || 1; - var tagName = "H" + level, - result = [], - currentTocEntry; + const tagName = "H" + level; + const result = []; function push(tocEntry) { if (tocEntry !== undefined) { @@ -98,8 +98,9 @@ } } - for (var i = 0; i < tocEntries.length; i++) { - var tocEntry = tocEntries[i]; + let currentTocEntry; + for (let i = 0; i < tocEntries.length; i++) { + const tocEntry = tocEntries[i]; if (tocEntry.tagName.toUpperCase() !== tagName) { if (currentTocEntry === undefined) { currentTocEntry = new TocEntry(); @@ -118,7 +119,7 @@ return { type: "output", filter: function(sourceHtml) { - var headerList = getHeaderEntries(sourceHtml); + let headerList = getHeaderEntries(sourceHtml); // No header found if (headerList.length === 0) { @@ -134,7 +135,7 @@ } // Build result and replace all [toc] - var result = + const result = '
    \n
      \n' + headerList.join("") + "
    \n
    \n"; return sourceHtml.replace(/\[toc\]/gi, result); }