Skip to content

Commit

Permalink
remove non-null assertion operator from std (part1) (denoland/deno#3900)
Browse files Browse the repository at this point in the history
  • Loading branch information
keroxp authored and denobot committed Feb 1, 2021
1 parent be019db commit ee8ec4b
Show file tree
Hide file tree
Showing 26 changed files with 147 additions and 89 deletions.
24 changes: 15 additions & 9 deletions datetime/mod.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { pad } from "../strings/pad.ts";
import { assert } from "../testing/mod.ts";

export type DateFormat = "mm-dd-yyyy" | "dd-mm-yyyy" | "yyyy-mm-dd";

function execForce(reg: RegExp, pat: string): RegExpExecArray {
const v = reg.exec(pat);
assert(v != null);
return v;
}
/**
* Parse date from string using format string
* @param dateStr Date string
Expand All @@ -16,15 +22,15 @@ export function parseDate(dateStr: string, format: DateFormat): Date {
switch (format) {
case "mm-dd-yyyy":
datePattern = /^(\d{2})-(\d{2})-(\d{4})$/;
[, m, d, y] = datePattern.exec(dateStr)!;
[, m, d, y] = execForce(datePattern, dateStr);
break;
case "dd-mm-yyyy":
datePattern = /^(\d{2})-(\d{2})-(\d{4})$/;
[, d, m, y] = datePattern.exec(dateStr)!;
[, d, m, y] = execForce(datePattern, dateStr);
break;
case "yyyy-mm-dd":
datePattern = /^(\d{4})-(\d{2})-(\d{2})$/;
[, y, m, d] = datePattern.exec(dateStr)!;
[, y, m, d] = execForce(datePattern, dateStr);
break;
default:
throw new Error("Invalid date format!");
Expand Down Expand Up @@ -57,27 +63,27 @@ export function parseDateTime(
switch (format) {
case "mm-dd-yyyy hh:mm":
datePattern = /^(\d{2})-(\d{2})-(\d{4}) (\d{2}):(\d{2})$/;
[, m, d, y, ho, mi] = datePattern.exec(datetimeStr)!;
[, m, d, y, ho, mi] = execForce(datePattern, datetimeStr);
break;
case "dd-mm-yyyy hh:mm":
datePattern = /^(\d{2})-(\d{2})-(\d{4}) (\d{2}):(\d{2})$/;
[, d, m, y, ho, mi] = datePattern.exec(datetimeStr)!;
[, d, m, y, ho, mi] = execForce(datePattern, datetimeStr);
break;
case "yyyy-mm-dd hh:mm":
datePattern = /^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})$/;
[, y, m, d, ho, mi] = datePattern.exec(datetimeStr)!;
[, y, m, d, ho, mi] = execForce(datePattern, datetimeStr);
break;
case "hh:mm mm-dd-yyyy":
datePattern = /^(\d{2}):(\d{2}) (\d{2})-(\d{2})-(\d{4})$/;
[, ho, mi, m, d, y] = datePattern.exec(datetimeStr)!;
[, ho, mi, m, d, y] = execForce(datePattern, datetimeStr);
break;
case "hh:mm dd-mm-yyyy":
datePattern = /^(\d{2}):(\d{2}) (\d{2})-(\d{2})-(\d{4})$/;
[, ho, mi, d, m, y] = datePattern.exec(datetimeStr)!;
[, ho, mi, d, m, y] = execForce(datePattern, datetimeStr);
break;
case "hh:mm yyyy-mm-dd":
datePattern = /^(\d{2}):(\d{2}) (\d{4})-(\d{2})-(\d{2})$/;
[, ho, mi, y, m, d] = datePattern.exec(datetimeStr)!;
[, ho, mi, y, m, d] = execForce(datePattern, datetimeStr);
break;
default:
throw new Error("Invalid datetime format!");
Expand Down
4 changes: 2 additions & 2 deletions encoding/base32.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ for (let i = 0, len = code.length; i < len; ++i) {
const placeHolderPadLookup = [0, 1, , 2, 3, , 4];
function _getPadLen(placeHoldersLen: number): number {
const maybeLen = placeHolderPadLookup[placeHoldersLen];
if (maybeLen === undefined) {
if (typeof maybeLen !== "number") {
throw new Error("Invalid pad length");
}
return maybeLen!;
return maybeLen;
}

function getLens(b32: string): [number, number] {
Expand Down
11 changes: 8 additions & 3 deletions examples/tests/xeval_test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { xeval } from "../xeval.ts";
import { stringsReader } from "../../io/util.ts";
import { decode, encode } from "../../strings/mod.ts";
import { assertEquals, assertStrContains } from "../../testing/asserts.ts";
import {
assertEquals,
assertStrContains,
assert
} from "../../testing/asserts.ts";
import { test } from "../../testing/mod.ts";
const { execPath, run } = Deno;

Expand Down Expand Up @@ -29,8 +33,9 @@ test(async function xevalCliReplvar(): Promise<void> {
stdout: "piped",
stderr: "null"
});
await p.stdin!.write(encode("hello"));
await p.stdin!.close();
assert(p.stdin != null);
await p.stdin.write(encode("hello"));
await p.stdin.close();
assertEquals(await p.status(), { code: 0, success: true });
assertEquals(decode(await p.output()).trimEnd(), "hello");
});
Expand Down
9 changes: 7 additions & 2 deletions fs/expand_glob.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
normalize
} from "../path/mod.ts";
import { WalkInfo, walk, walkSync } from "./walk.ts";
import { assert } from "../testing/mod.ts";
const { ErrorKind, cwd, stat, statSync } = Deno;
type ErrorKind = Deno.ErrorKind;
type DenoError = Deno.DenoError<ErrorKind>;
Expand Down Expand Up @@ -80,7 +81,9 @@ export async function* expandGlob(

let fixedRoot = winRoot != undefined ? winRoot : "/";
while (segments.length > 0 && !isGlob(segments[0])) {
fixedRoot = joinGlobs([fixedRoot, segments.shift()!], globOptions);
const seg = segments.shift();
assert(seg != null);
fixedRoot = joinGlobs([fixedRoot, seg], globOptions);
}

let fixedRootInfo: WalkInfo;
Expand Down Expand Up @@ -182,7 +185,9 @@ export function* expandGlobSync(

let fixedRoot = winRoot != undefined ? winRoot : "/";
while (segments.length > 0 && !isGlob(segments[0])) {
fixedRoot = joinGlobs([fixedRoot, segments.shift()!], globOptions);
const seg = segments.shift();
assert(seg != null);
fixedRoot = joinGlobs([fixedRoot, seg], globOptions);
}

let fixedRootInfo: WalkInfo;
Expand Down
8 changes: 5 additions & 3 deletions fs/walk.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Documentation and interface for walk were adapted from Go
// https://golang.org/pkg/path/filepath/#Walk
// Copyright 2009 The Go Authors. All rights reserved. BSD license.
import { unimplemented } from "../testing/asserts.ts";
import { unimplemented, assert } from "../testing/asserts.ts";
import { join } from "../path/mod.ts";
const { readDir, readDirSync, stat, statSync } = Deno;
type FileInfo = Deno.FileInfo;
Expand Down Expand Up @@ -90,7 +90,8 @@ export async function* walk(
}
}

const filename = join(root, info.name!);
assert(info.name != null);
const filename = join(root, info.name);

if (info.isFile()) {
if (includeFiles && include(filename, exts, match, skip)) {
Expand Down Expand Up @@ -142,7 +143,8 @@ export function* walkSync(
}
}

const filename = join(root, info.name!);
assert(info.name != null);
const filename = join(root, info.name);

if (info.isFile()) {
if (includeFiles && include(filename, exts, match, skip)) {
Expand Down
14 changes: 8 additions & 6 deletions http/cookie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ function toString(cookie: Cookie): string {
if (cookie.httpOnly) {
out.push("HttpOnly");
}
if (Number.isInteger(cookie.maxAge!)) {
assert(cookie.maxAge! > 0, "Max-Age must be an integer superior to 0");
if (Number.isInteger(cookie.maxAge)) {
assert(cookie.maxAge > 0, "Max-Age must be an integer superior to 0");
out.push(`Max-Age=${cookie.maxAge}`);
}
if (cookie.domain) {
Expand All @@ -73,12 +73,14 @@ function toString(cookie: Cookie): string {
* @param req Server Request
*/
export function getCookies(req: ServerRequest): Cookies {
if (req.headers.has("Cookie")) {
const cookie = req.headers.get("Cookie");
if (cookie != null) {
const out: Cookies = {};
const c = req.headers.get("Cookie")!.split(";");
const c = cookie.split(";");
for (const kv of c) {
const cookieVal = kv.split("=");
const key = cookieVal.shift()!.trim();
const [cookieKey, ...cookieVal] = kv.split("=");
assert(cookieKey != null);
const key = cookieKey.trim();
out[key] = cookieVal.join("=");
}
return out;
Expand Down
2 changes: 1 addition & 1 deletion http/cookie_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ test({
const res: Response = {};
delCookie(res, "deno");
assertEquals(
res.headers!.get("Set-Cookie"),
res.headers?.get("Set-Cookie"),
"deno=; Expires=Thu, 01 Jan 1970 00:00:00 GMT"
);
}
Expand Down
6 changes: 3 additions & 3 deletions http/file_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ function modeToString(isDir: boolean, maybeMode: number | null): string {
if (maybeMode === null) {
return "(unknown mode)";
}
const mode = maybeMode!.toString(8);
const mode = maybeMode.toString(8);
if (mode.length < 3) {
return "(unknown mode)";
}
Expand Down Expand Up @@ -186,8 +186,8 @@ function setCORS(res: Response): void {
if (!res.headers) {
res.headers = new Headers();
}
res.headers!.append("access-control-allow-origin", "*");
res.headers!.append(
res.headers.append("access-control-allow-origin", "*");
res.headers.append(
"access-control-allow-headers",
"Origin, X-Requested-With, Content-Type, Accept, Range"
);
Expand Down
20 changes: 12 additions & 8 deletions http/file_server_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ async function startFileServer(): Promise<void> {
stdout: "piped"
});
// Once fileServer is ready it will write to its stdout.
const r = new TextProtoReader(new BufReader(fileServer.stdout!));
assert(fileServer.stdout != null);
const r = new TextProtoReader(new BufReader(fileServer.stdout));
const s = await r.readLine();
assert(s !== Deno.EOF && s.includes("server listening"));
}

function killFileServer(): void {
fileServer.close();
fileServer.stdout!.close();
fileServer.stdout?.close();
}

test(async function serveFile(): Promise<void> {
Expand Down Expand Up @@ -102,8 +103,10 @@ test(async function servePermissionDenied(): Promise<void> {
stdout: "piped",
stderr: "piped"
});
const reader = new TextProtoReader(new BufReader(deniedServer.stdout!));
const errReader = new TextProtoReader(new BufReader(deniedServer.stderr!));
assert(deniedServer.stdout != null);
const reader = new TextProtoReader(new BufReader(deniedServer.stdout));
assert(deniedServer.stderr != null);
const errReader = new TextProtoReader(new BufReader(deniedServer.stderr));
const s = await reader.readLine();
assert(s !== Deno.EOF && s.includes("server listening"));

Expand All @@ -115,8 +118,8 @@ test(async function servePermissionDenied(): Promise<void> {
);
} finally {
deniedServer.close();
deniedServer.stdout!.close();
deniedServer.stderr!.close();
deniedServer.stdout.close();
deniedServer.stderr.close();
}
});

Expand All @@ -125,9 +128,10 @@ test(async function printHelp(): Promise<void> {
args: [Deno.execPath(), "run", "http/file_server.ts", "--help"],
stdout: "piped"
});
const r = new TextProtoReader(new BufReader(helpProcess.stdout!));
assert(helpProcess.stdout != null);
const r = new TextProtoReader(new BufReader(helpProcess.stdout));
const s = await r.readLine();
assert(s !== Deno.EOF && s.includes("Deno File Server"));
helpProcess.close();
helpProcess.stdout!.close();
helpProcess.stdout.close();
});
5 changes: 3 additions & 2 deletions http/racing_server_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ async function startServer(): Promise<void> {
stdout: "piped"
});
// Once racing server is ready it will write to its stdout.
const r = new TextProtoReader(new BufReader(server.stdout!));
assert(server.stdout != null);
const r = new TextProtoReader(new BufReader(server.stdout));
const s = await r.readLine();
assert(s !== Deno.EOF && s.includes("Racing server listening..."));
}
function killServer(): void {
server.close();
server.stdout!.close();
server.stdout?.close();
}

const input = `GET / HTTP/1.1
Expand Down
30 changes: 17 additions & 13 deletions http/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,10 @@ export async function writeResponse(w: Writer, r: Response): Promise<void> {
let out = `HTTP/${protoMajor}.${protoMinor} ${statusCode} ${statusText}\r\n`;

setContentLength(r);
const headers = r.headers!;
assert(r.headers != null);
const headers = r.headers;

for (const [key, value] of headers!) {
for (const [key, value] of headers) {
out += `${key}: ${value}\r\n`;
}
out += "\r\n";
Expand All @@ -88,7 +89,9 @@ export async function writeResponse(w: Writer, r: Response): Promise<void> {
const n = await writer.write(r.body);
assert(n === r.body.byteLength);
} else if (headers.has("content-length")) {
const bodyLength = parseInt(headers.get("content-length")!);
const contentLength = headers.get("content-length");
assert(contentLength != null);
const bodyLength = parseInt(contentLength);
const n = await copy(writer, r.body);
assert(n === bodyLength);
} else {
Expand Down Expand Up @@ -129,8 +132,9 @@ export class ServerRequest {
// undefined means not cached.
// null means invalid or not provided.
if (this._contentLength === undefined) {
if (this.headers.has("content-length")) {
this._contentLength = +this.headers.get("content-length")!;
const cl = this.headers.get("content-length");
if (cl) {
this._contentLength = parseInt(cl);
// Convert NaN to null (as NaN harder to test)
if (Number.isNaN(this._contentLength)) {
this._contentLength = null;
Expand Down Expand Up @@ -190,12 +194,12 @@ export class ServerRequest {
}
yield nread;
} else {
if (this.headers.has("transfer-encoding")) {
const transferEncodings = this.headers
.get("transfer-encoding")!
const transferEncoding = this.headers.get("transfer-encoding");
if (transferEncoding) {
const parts = transferEncoding
.split(",")
.map((e): string => e.trim().toLowerCase());
if (transferEncodings.includes("chunked")) {
if (parts.includes("chunked")) {
// Based on https://tools.ietf.org/html/rfc2616#section-19.4.6
const tp = new TextProtoReader(this.r);
let line = await tp.readLine();
Expand Down Expand Up @@ -413,7 +417,7 @@ export class Server implements AsyncIterable<ServerRequest> {

// Wait for the request to be processed before we accept a new request on
// this connection.
const procError = await req!.done;
const procError = await req.done;
if (procError) {
// Something bad happened during response.
// (likely other side closed during pipelined req)
Expand All @@ -422,12 +426,12 @@ export class Server implements AsyncIterable<ServerRequest> {
}
}

if (req! === Deno.EOF) {
if (req === Deno.EOF) {
// The connection was gracefully closed.
} else if (err) {
} else if (err && req) {
// An error was thrown while parsing request headers.
try {
await writeResponse(req!.w, {
await writeResponse(req.w, {
status: 400,
body: encoder.encode(`${err.message}\r\n\r\n`)
});
Expand Down
9 changes: 5 additions & 4 deletions http/server_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -506,8 +506,7 @@ test(async function testReadRequestError(): Promise<void> {
for (const test of testCases) {
const reader = new BufReader(new StringReader(test.in));
let err;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let req: any;
let req: ServerRequest | Deno.EOF;
try {
req = await readRequest(mockConn as Deno.Conn, reader);
} catch (e) {
Expand All @@ -520,10 +519,12 @@ test(async function testReadRequestError(): Promise<void> {
} else if (test.err) {
assert(err instanceof (test.err as typeof UnexpectedEOFError));
} else {
assert(req instanceof ServerRequest);
assert(test.headers != null);
assertEquals(err, undefined);
assertNotEquals(req, Deno.EOF);
for (const h of test.headers!) {
assertEquals((req! as ServerRequest).headers.get(h.key), h.value);
for (const h of test.headers) {
assertEquals(req.headers.get(h.key), h.value);
}
}
}
Expand Down
Loading

0 comments on commit ee8ec4b

Please sign in to comment.