1
0
Fork 0
mirror of https://github.com/imjasonh/deno-image synced 2026-07-07 00:33:45 +00:00

remove vendor and .gitignore

Signed-off-by: Carlos Santana <csantana23@gmail.com>
This commit is contained in:
Carlos Santana 2021-08-27 12:29:10 -04:00
parent d9993f6b98
commit 18da0fca18
14 changed files with 1 additions and 2424 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
example
vendor/**

View file

@ -1,703 +0,0 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
// This module is browser compatible. Do not rely on good formatting of values
// for AssertionError messages in browsers.
import {
bgGreen,
bgRed,
bold,
gray,
green,
red,
stripColor,
white,
} from "../fmt/colors.ts";
import { diff, DiffResult, diffstr, DiffType } from "./_diff.ts";
const CAN_NOT_DISPLAY = "[Cannot display]";
interface Constructor {
// deno-lint-ignore no-explicit-any
new (...args: any[]): any;
}
export class AssertionError extends Error {
constructor(message: string) {
super(message);
this.name = "AssertionError";
}
}
/**
* Converts the input into a string. Objects, Sets and Maps are sorted so as to
* make tests less flaky
* @param v Value to be formatted
*/
export function _format(v: unknown): string {
// deno-lint-ignore no-explicit-any
const { Deno } = globalThis as any;
return typeof Deno?.inspect === "function"
? Deno.inspect(v, {
depth: Infinity,
sorted: true,
trailingComma: true,
compact: false,
iterableLimit: Infinity,
})
: `"${String(v).replace(/(?=["\\])/g, "\\")}"`;
}
/**
* Colors the output of assertion diffs
* @param diffType Difference type, either added or removed
*/
function createColor(
diffType: DiffType,
{ background = false } = {},
): (s: string) => string {
switch (diffType) {
case DiffType.added:
return (s: string): string =>
background ? bgGreen(white(s)) : green(bold(s));
case DiffType.removed:
return (s: string): string => background ? bgRed(white(s)) : red(bold(s));
default:
return white;
}
}
/**
* Prefixes `+` or `-` in diff output
* @param diffType Difference type, either added or removed
*/
function createSign(diffType: DiffType): string {
switch (diffType) {
case DiffType.added:
return "+ ";
case DiffType.removed:
return "- ";
default:
return " ";
}
}
function buildMessage(
diffResult: ReadonlyArray<DiffResult<string>>,
{ stringDiff = false } = {},
): string[] {
const messages: string[] = [], diffMessages: string[] = [];
messages.push("");
messages.push("");
messages.push(
` ${gray(bold("[Diff]"))} ${red(bold("Actual"))} / ${
green(bold("Expected"))
}`,
);
messages.push("");
messages.push("");
diffResult.forEach((result: DiffResult<string>): void => {
const c = createColor(result.type);
const line = result.details?.map((detail) =>
detail.type !== DiffType.common
? createColor(detail.type, { background: true })(detail.value)
: detail.value
).join("") ?? result.value;
diffMessages.push(c(`${createSign(result.type)}${line}`));
});
messages.push(...(stringDiff ? [diffMessages.join("")] : diffMessages));
messages.push("");
return messages;
}
function isKeyedCollection(x: unknown): x is Set<unknown> {
return [Symbol.iterator, "size"].every((k) => k in (x as Set<unknown>));
}
/**
* Deep equality comparison used in assertions
* @param c actual value
* @param d expected value
*/
export function equal(c: unknown, d: unknown): boolean {
const seen = new Map();
return (function compare(a: unknown, b: unknown): boolean {
// Have to render RegExp & Date for string comparison
// unless it's mistreated as object
if (
a &&
b &&
((a instanceof RegExp && b instanceof RegExp) ||
(a instanceof URL && b instanceof URL))
) {
return String(a) === String(b);
}
if (a instanceof Date && b instanceof Date) {
const aTime = a.getTime();
const bTime = b.getTime();
// Check for NaN equality manually since NaN is not
// equal to itself.
if (Number.isNaN(aTime) && Number.isNaN(bTime)) {
return true;
}
return a.getTime() === b.getTime();
}
if (Object.is(a, b)) {
return true;
}
if (a && typeof a === "object" && b && typeof b === "object") {
if (a && b && !constructorsEqual(a, b)) {
return false;
}
if (a instanceof WeakMap || b instanceof WeakMap) {
if (!(a instanceof WeakMap && b instanceof WeakMap)) return false;
throw new TypeError("cannot compare WeakMap instances");
}
if (a instanceof WeakSet || b instanceof WeakSet) {
if (!(a instanceof WeakSet && b instanceof WeakSet)) return false;
throw new TypeError("cannot compare WeakSet instances");
}
if (seen.get(a) === b) {
return true;
}
if (Object.keys(a || {}).length !== Object.keys(b || {}).length) {
return false;
}
if (isKeyedCollection(a) && isKeyedCollection(b)) {
if (a.size !== b.size) {
return false;
}
let unmatchedEntries = a.size;
for (const [aKey, aValue] of a.entries()) {
for (const [bKey, bValue] of b.entries()) {
/* Given that Map keys can be references, we need
* to ensure that they are also deeply equal */
if (
(aKey === aValue && bKey === bValue && compare(aKey, bKey)) ||
(compare(aKey, bKey) && compare(aValue, bValue))
) {
unmatchedEntries--;
}
}
}
return unmatchedEntries === 0;
}
const merged = { ...a, ...b };
for (
const key of [
...Object.getOwnPropertyNames(merged),
...Object.getOwnPropertySymbols(merged),
]
) {
type Key = keyof typeof merged;
if (!compare(a && a[key as Key], b && b[key as Key])) {
return false;
}
if (((key in a) && (!(key in b))) || ((key in b) && (!(key in a)))) {
return false;
}
}
seen.set(a, b);
if (a instanceof WeakRef || b instanceof WeakRef) {
if (!(a instanceof WeakRef && b instanceof WeakRef)) return false;
return compare(a.deref(), b.deref());
}
return true;
}
return false;
})(c, d);
}
// deno-lint-ignore ban-types
function constructorsEqual(a: object, b: object) {
return a.constructor === b.constructor ||
a.constructor === Object && !b.constructor ||
!a.constructor && b.constructor === Object;
}
/** Make an assertion, error will be thrown if `expr` does not have truthy value. */
export function assert(expr: unknown, msg = ""): asserts expr {
if (!expr) {
throw new AssertionError(msg);
}
}
/**
* Make an assertion that `actual` and `expected` are equal, deeply. If not
* deeply equal, then throw.
*
* Type parameter can be specified to ensure values under comparison have the same type.
* For example:
* ```ts
* import { assertEquals } from "./asserts.ts";
*
* assertEquals<number>(1, 2)
* ```
*/
export function assertEquals(
actual: unknown,
expected: unknown,
msg?: string,
): void;
export function assertEquals<T>(actual: T, expected: T, msg?: string): void;
export function assertEquals(
actual: unknown,
expected: unknown,
msg?: string,
): void {
if (equal(actual, expected)) {
return;
}
let message = "";
const actualString = _format(actual);
const expectedString = _format(expected);
try {
const stringDiff = (typeof actual === "string") &&
(typeof expected === "string");
const diffResult = stringDiff
? diffstr(actual as string, expected as string)
: diff(actualString.split("\n"), expectedString.split("\n"));
const diffMsg = buildMessage(diffResult, { stringDiff }).join("\n");
message = `Values are not equal:\n${diffMsg}`;
} catch {
message = `\n${red(CAN_NOT_DISPLAY)} + \n\n`;
}
if (msg) {
message = msg;
}
throw new AssertionError(message);
}
/**
* Make an assertion that `actual` and `expected` are not equal, deeply.
* If not then throw.
*
* Type parameter can be specified to ensure values under comparison have the same type.
* For example:
* ```ts
* import { assertNotEquals } from "./asserts.ts";
*
* assertNotEquals<number>(1, 2)
* ```
*/
export function assertNotEquals(
actual: unknown,
expected: unknown,
msg?: string,
): void;
export function assertNotEquals<T>(actual: T, expected: T, msg?: string): void;
export function assertNotEquals(
actual: unknown,
expected: unknown,
msg?: string,
): void {
if (!equal(actual, expected)) {
return;
}
let actualString: string;
let expectedString: string;
try {
actualString = String(actual);
} catch {
actualString = "[Cannot display]";
}
try {
expectedString = String(expected);
} catch {
expectedString = "[Cannot display]";
}
if (!msg) {
msg = `actual: ${actualString} expected: ${expectedString}`;
}
throw new AssertionError(msg);
}
/**
* Make an assertion that `actual` and `expected` are strictly equal. If
* not then throw.
*
* ```ts
* import { assertStrictEquals } from "./asserts.ts";
*
* assertStrictEquals(1, 2)
* ```
*/
export function assertStrictEquals(
actual: unknown,
expected: unknown,
msg?: string,
): void;
export function assertStrictEquals<T>(
actual: T,
expected: T,
msg?: string,
): void;
export function assertStrictEquals(
actual: unknown,
expected: unknown,
msg?: string,
): void {
if (actual === expected) {
return;
}
let message: string;
if (msg) {
message = msg;
} else {
const actualString = _format(actual);
const expectedString = _format(expected);
if (actualString === expectedString) {
const withOffset = actualString
.split("\n")
.map((l) => ` ${l}`)
.join("\n");
message =
`Values have the same structure but are not reference-equal:\n\n${
red(withOffset)
}\n`;
} else {
try {
const stringDiff = (typeof actual === "string") &&
(typeof expected === "string");
const diffResult = stringDiff
? diffstr(actual as string, expected as string)
: diff(actualString.split("\n"), expectedString.split("\n"));
const diffMsg = buildMessage(diffResult, { stringDiff }).join("\n");
message = `Values are not strictly equal:\n${diffMsg}`;
} catch {
message = `\n${red(CAN_NOT_DISPLAY)} + \n\n`;
}
}
}
throw new AssertionError(message);
}
/**
* Make an assertion that `actual` and `expected` are not strictly equal.
* If the values are strictly equal then throw.
*
* ```ts
* import { assertNotStrictEquals } from "./asserts.ts";
*
* assertNotStrictEquals(1, 1)
* ```
*/
export function assertNotStrictEquals(
actual: unknown,
expected: unknown,
msg?: string,
): void;
export function assertNotStrictEquals<T>(
actual: T,
expected: T,
msg?: string,
): void;
export function assertNotStrictEquals(
actual: unknown,
expected: unknown,
msg?: string,
): void {
if (actual !== expected) {
return;
}
throw new AssertionError(
msg ?? `Expected "actual" to be strictly unequal to: ${_format(actual)}\n`,
);
}
/**
* Make an assertion that actual is not null or undefined.
* If not then throw.
*/
export function assertExists<T>(
actual: T,
msg?: string,
): asserts actual is NonNullable<T> {
if (actual === undefined || actual === null) {
if (!msg) {
msg = `actual: "${actual}" expected to not be null or undefined`;
}
throw new AssertionError(msg);
}
}
/**
* Make an assertion that actual includes expected. If not
* then throw.
*/
export function assertStringIncludes(
actual: string,
expected: string,
msg?: string,
): void {
if (!actual.includes(expected)) {
if (!msg) {
msg = `actual: "${actual}" expected to contain: "${expected}"`;
}
throw new AssertionError(msg);
}
}
/**
* Make an assertion that `actual` includes the `expected` values.
* If not then an error will be thrown.
*
* Type parameter can be specified to ensure values under comparison have the same type.
* For example:
*
* ```ts
* import { assertArrayIncludes } from "./asserts.ts";
*
* assertArrayIncludes<number>([1, 2], [2])
* ```
*/
export function assertArrayIncludes(
actual: ArrayLike<unknown>,
expected: ArrayLike<unknown>,
msg?: string,
): void;
export function assertArrayIncludes<T>(
actual: ArrayLike<T>,
expected: ArrayLike<T>,
msg?: string,
): void;
export function assertArrayIncludes(
actual: ArrayLike<unknown>,
expected: ArrayLike<unknown>,
msg?: string,
): void {
const missing: unknown[] = [];
for (let i = 0; i < expected.length; i++) {
let found = false;
for (let j = 0; j < actual.length; j++) {
if (equal(expected[i], actual[j])) {
found = true;
break;
}
}
if (!found) {
missing.push(expected[i]);
}
}
if (missing.length === 0) {
return;
}
if (!msg) {
msg = `actual: "${_format(actual)}" expected to include: "${
_format(expected)
}"\nmissing: ${_format(missing)}`;
}
throw new AssertionError(msg);
}
/**
* Make an assertion that `actual` match RegExp `expected`. If not
* then throw.
*/
export function assertMatch(
actual: string,
expected: RegExp,
msg?: string,
): void {
if (!expected.test(actual)) {
if (!msg) {
msg = `actual: "${actual}" expected to match: "${expected}"`;
}
throw new AssertionError(msg);
}
}
/**
* Make an assertion that `actual` not match RegExp `expected`. If match
* then throw.
*/
export function assertNotMatch(
actual: string,
expected: RegExp,
msg?: string,
): void {
if (expected.test(actual)) {
if (!msg) {
msg = `actual: "${actual}" expected to not match: "${expected}"`;
}
throw new AssertionError(msg);
}
}
/**
* Make an assertion that `actual` object is a subset of `expected` object, deeply.
* If not, then throw.
*/
export function assertObjectMatch(
// deno-lint-ignore no-explicit-any
actual: Record<PropertyKey, any>,
expected: Record<PropertyKey, unknown>,
): void {
type loose = Record<PropertyKey, unknown>;
const seen = new WeakMap();
return assertEquals(
(function filter(a: loose, b: loose): loose {
// Prevent infinite loop with circular references with same filter
if ((seen.has(a)) && (seen.get(a) === b)) {
return a;
}
seen.set(a, b);
// Filter keys and symbols which are present in both actual and expected
const filtered = {} as loose;
const entries = [
...Object.getOwnPropertyNames(a),
...Object.getOwnPropertySymbols(a),
]
.filter((key) => key in b)
.map((key) => [key, a[key as string]]) as Array<[string, unknown]>;
for (const [key, value] of entries) {
// On array references, build a filtered array and filter nested objects inside
if (Array.isArray(value)) {
const subset = (b as loose)[key];
if (Array.isArray(subset)) {
filtered[key] = value
.slice(0, subset.length)
.map((element, index) => {
const subsetElement = subset[index];
if ((typeof subsetElement === "object") && (subsetElement)) {
return filter(element, subsetElement);
}
return element;
});
continue;
}
} // On nested objects references, build a filtered object recursively
else if (typeof value === "object") {
const subset = (b as loose)[key];
if ((typeof subset === "object") && (subset)) {
filtered[key] = filter(value as loose, subset as loose);
continue;
}
}
filtered[key] = value;
}
return filtered;
})(actual, expected),
expected,
);
}
/**
* Forcefully throws a failed assertion
*/
export function fail(msg?: string): never {
assert(false, `Failed assertion${msg ? `: ${msg}` : "."}`);
}
/**
* Executes a function, expecting it to throw. If it does not, then it
* throws. An error class and a string that should be included in the
* error message can also be asserted.
*/
export function assertThrows<T = void>(
fn: () => T,
ErrorClass?: Constructor,
msgIncludes = "",
msg?: string,
): void {
let doesThrow = false;
try {
fn();
} catch (e) {
if (e instanceof Error === false) {
throw new AssertionError("A non-Error object was thrown.");
}
if (ErrorClass && !(e instanceof ErrorClass)) {
msg =
`Expected error to be instance of "${ErrorClass.name}", but was "${e.constructor.name}"${
msg ? `: ${msg}` : "."
}`;
throw new AssertionError(msg);
}
if (
msgIncludes &&
!stripColor(e.message).includes(stripColor(msgIncludes))
) {
msg =
`Expected error message to include "${msgIncludes}", but got "${e.message}"${
msg ? `: ${msg}` : "."
}`;
throw new AssertionError(msg);
}
doesThrow = true;
}
if (!doesThrow) {
msg = `Expected function to throw${msg ? `: ${msg}` : "."}`;
throw new AssertionError(msg);
}
}
/**
* Executes a function which returns a promise, expecting it to throw or reject.
* If it does not, then it throws. An error class and a string that should be
* included in the error message can also be asserted.
*/
export async function assertRejects<T = void>(
fn: () => Promise<T>,
ErrorClass?: Constructor,
msgIncludes = "",
msg?: string,
): Promise<void> {
let doesThrow = false;
try {
await fn();
} catch (e) {
if (e instanceof Error === false) {
throw new AssertionError("A non-Error object was thrown or rejected.");
}
if (ErrorClass && !(e instanceof ErrorClass)) {
msg =
`Expected error to be instance of "${ErrorClass.name}", but was "${e.constructor.name}"${
msg ? `: ${msg}` : "."
}`;
throw new AssertionError(msg);
}
if (
msgIncludes &&
!stripColor(e.message).includes(stripColor(msgIncludes))
) {
msg =
`Expected error message to include "${msgIncludes}", but got "${e.message}"${
msg ? `: ${msg}` : "."
}`;
throw new AssertionError(msg);
}
doesThrow = true;
}
if (!doesThrow) {
msg = `Expected function to throw${msg ? `: ${msg}` : "."}`;
throw new AssertionError(msg);
}
}
/**
* Executes a function which returns a promise, expecting it to throw or reject.
* If it does not, then it throws. An error class and a string that should be
* included in the error message can also be asserted.
*
* @deprecated
*/
export { assertRejects as assertThrowsAsync };
/** Use this to stub out methods that will throw when invoked. */
export function unimplemented(msg?: string): never {
throw new AssertionError(msg || "unimplemented");
}
/** Use this to assert unreachable code. */
export function unreachable(): never {
throw new AssertionError("unreachable");
}

View file

@ -1,16 +0,0 @@
{
"headers": {
"cache-control": "public, max-age=31536000, immutable",
"x-amz-request-id": "5WK20JDP4JGMDA0M",
"x-amz-id-2": "0l7bjBDsKtleLd1Grvjt2SeQI/+2ua8jGuVBG2Z/h45Meq0BMgl9J82vZTLPTrORGqpznqVFs3E=",
"x-amz-version-id": "qW9eDWU3kybHVD1gOHGerosW7UEZaMeQ",
"content-length": "18928",
"content-type": "application/typescript; charset=utf-8",
"last-modified": "Mon, 23 Aug 2021 22:19:15 GMT",
"access-control-allow-origin": "*",
"server": "AmazonS3",
"date": "Tue, 24 Aug 2021 13:53:42 GMT",
"etag": "\"3c51595bb9af62c421e371635ad7b9e9\""
},
"url": "https://deno.land/std@0.106.0/testing/asserts.ts"
}

View file

@ -1,526 +0,0 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
// A module to print ANSI terminal colors. Inspired by chalk, kleur, and colors
// on npm.
//
// ```
// import { bgBlue, red, bold } from "https://deno.land/std/fmt/colors.ts";
// console.log(bgBlue(red(bold("Hello world!"))));
// ```
//
// This module supports `NO_COLOR` environmental variable disabling any coloring
// if `NO_COLOR` is set.
//
// This module is browser compatible.
// deno-lint-ignore no-explicit-any
const { Deno } = globalThis as any;
const noColor = typeof Deno?.noColor === "boolean"
? Deno.noColor as boolean
: true;
interface Code {
open: string;
close: string;
regexp: RegExp;
}
/** RGB 8-bits per channel. Each in range `0->255` or `0x00->0xff` */
interface Rgb {
r: number;
g: number;
b: number;
}
let enabled = !noColor;
/**
* Set changing text color to enabled or disabled
* @param value
*/
export function setColorEnabled(value: boolean): void {
if (noColor) {
return;
}
enabled = value;
}
/** Get whether text color change is enabled or disabled. */
export function getColorEnabled(): boolean {
return enabled;
}
/**
* Builds color code
* @param open
* @param close
*/
function code(open: number[], close: number): Code {
return {
open: `\x1b[${open.join(";")}m`,
close: `\x1b[${close}m`,
regexp: new RegExp(`\\x1b\\[${close}m`, "g"),
};
}
/**
* Applies color and background based on color code and its associated text
* @param str text to apply color settings to
* @param code color code to apply
*/
function run(str: string, code: Code): string {
return enabled
? `${code.open}${str.replace(code.regexp, code.open)}${code.close}`
: str;
}
/**
* Reset the text modified
* @param str text to reset
*/
export function reset(str: string): string {
return run(str, code([0], 0));
}
/**
* Make the text bold.
* @param str text to make bold
*/
export function bold(str: string): string {
return run(str, code([1], 22));
}
/**
* The text emits only a small amount of light.
* @param str text to dim
*/
export function dim(str: string): string {
return run(str, code([2], 22));
}
/**
* Make the text italic.
* @param str text to make italic
*/
export function italic(str: string): string {
return run(str, code([3], 23));
}
/**
* Make the text underline.
* @param str text to underline
*/
export function underline(str: string): string {
return run(str, code([4], 24));
}
/**
* Invert background color and text color.
* @param str text to invert its color
*/
export function inverse(str: string): string {
return run(str, code([7], 27));
}
/**
* Make the text hidden.
* @param str text to hide
*/
export function hidden(str: string): string {
return run(str, code([8], 28));
}
/**
* Put horizontal line through the center of the text.
* @param str text to strike through
*/
export function strikethrough(str: string): string {
return run(str, code([9], 29));
}
/**
* Set text color to black.
* @param str text to make black
*/
export function black(str: string): string {
return run(str, code([30], 39));
}
/**
* Set text color to red.
* @param str text to make red
*/
export function red(str: string): string {
return run(str, code([31], 39));
}
/**
* Set text color to green.
* @param str text to make green
*/
export function green(str: string): string {
return run(str, code([32], 39));
}
/**
* Set text color to yellow.
* @param str text to make yellow
*/
export function yellow(str: string): string {
return run(str, code([33], 39));
}
/**
* Set text color to blue.
* @param str text to make blue
*/
export function blue(str: string): string {
return run(str, code([34], 39));
}
/**
* Set text color to magenta.
* @param str text to make magenta
*/
export function magenta(str: string): string {
return run(str, code([35], 39));
}
/**
* Set text color to cyan.
* @param str text to make cyan
*/
export function cyan(str: string): string {
return run(str, code([36], 39));
}
/**
* Set text color to white.
* @param str text to make white
*/
export function white(str: string): string {
return run(str, code([37], 39));
}
/**
* Set text color to gray.
* @param str text to make gray
*/
export function gray(str: string): string {
return brightBlack(str);
}
/**
* Set text color to bright black.
* @param str text to make bright-black
*/
export function brightBlack(str: string): string {
return run(str, code([90], 39));
}
/**
* Set text color to bright red.
* @param str text to make bright-red
*/
export function brightRed(str: string): string {
return run(str, code([91], 39));
}
/**
* Set text color to bright green.
* @param str text to make bright-green
*/
export function brightGreen(str: string): string {
return run(str, code([92], 39));
}
/**
* Set text color to bright yellow.
* @param str text to make bright-yellow
*/
export function brightYellow(str: string): string {
return run(str, code([93], 39));
}
/**
* Set text color to bright blue.
* @param str text to make bright-blue
*/
export function brightBlue(str: string): string {
return run(str, code([94], 39));
}
/**
* Set text color to bright magenta.
* @param str text to make bright-magenta
*/
export function brightMagenta(str: string): string {
return run(str, code([95], 39));
}
/**
* Set text color to bright cyan.
* @param str text to make bright-cyan
*/
export function brightCyan(str: string): string {
return run(str, code([96], 39));
}
/**
* Set text color to bright white.
* @param str text to make bright-white
*/
export function brightWhite(str: string): string {
return run(str, code([97], 39));
}
/**
* Set background color to black.
* @param str text to make its background black
*/
export function bgBlack(str: string): string {
return run(str, code([40], 49));
}
/**
* Set background color to red.
* @param str text to make its background red
*/
export function bgRed(str: string): string {
return run(str, code([41], 49));
}
/**
* Set background color to green.
* @param str text to make its background green
*/
export function bgGreen(str: string): string {
return run(str, code([42], 49));
}
/**
* Set background color to yellow.
* @param str text to make its background yellow
*/
export function bgYellow(str: string): string {
return run(str, code([43], 49));
}
/**
* Set background color to blue.
* @param str text to make its background blue
*/
export function bgBlue(str: string): string {
return run(str, code([44], 49));
}
/**
* Set background color to magenta.
* @param str text to make its background magenta
*/
export function bgMagenta(str: string): string {
return run(str, code([45], 49));
}
/**
* Set background color to cyan.
* @param str text to make its background cyan
*/
export function bgCyan(str: string): string {
return run(str, code([46], 49));
}
/**
* Set background color to white.
* @param str text to make its background white
*/
export function bgWhite(str: string): string {
return run(str, code([47], 49));
}
/**
* Set background color to bright black.
* @param str text to make its background bright-black
*/
export function bgBrightBlack(str: string): string {
return run(str, code([100], 49));
}
/**
* Set background color to bright red.
* @param str text to make its background bright-red
*/
export function bgBrightRed(str: string): string {
return run(str, code([101], 49));
}
/**
* Set background color to bright green.
* @param str text to make its background bright-green
*/
export function bgBrightGreen(str: string): string {
return run(str, code([102], 49));
}
/**
* Set background color to bright yellow.
* @param str text to make its background bright-yellow
*/
export function bgBrightYellow(str: string): string {
return run(str, code([103], 49));
}
/**
* Set background color to bright blue.
* @param str text to make its background bright-blue
*/
export function bgBrightBlue(str: string): string {
return run(str, code([104], 49));
}
/**
* Set background color to bright magenta.
* @param str text to make its background bright-magenta
*/
export function bgBrightMagenta(str: string): string {
return run(str, code([105], 49));
}
/**
* Set background color to bright cyan.
* @param str text to make its background bright-cyan
*/
export function bgBrightCyan(str: string): string {
return run(str, code([106], 49));
}
/**
* Set background color to bright white.
* @param str text to make its background bright-white
*/
export function bgBrightWhite(str: string): string {
return run(str, code([107], 49));
}
/* Special Color Sequences */
/**
* Clam and truncate color codes
* @param n
* @param max number to truncate to
* @param min number to truncate from
*/
function clampAndTruncate(n: number, max = 255, min = 0): number {
return Math.trunc(Math.max(Math.min(n, max), min));
}
/**
* Set text color using paletted 8bit colors.
* https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit
* @param str text color to apply paletted 8bit colors to
* @param color code
*/
export function rgb8(str: string, color: number): string {
return run(str, code([38, 5, clampAndTruncate(color)], 39));
}
/**
* Set background color using paletted 8bit colors.
* https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit
* @param str text color to apply paletted 8bit background colors to
* @param color code
*/
export function bgRgb8(str: string, color: number): string {
return run(str, code([48, 5, clampAndTruncate(color)], 49));
}
/**
* Set text color using 24bit rgb.
* `color` can be a number in range `0x000000` to `0xffffff` or
* an `Rgb`.
*
* To produce the color magenta:
*
* rgb24("foo", 0xff00ff);
* rgb24("foo", {r: 255, g: 0, b: 255});
* @param str text color to apply 24bit rgb to
* @param color code
*/
export function rgb24(str: string, color: number | Rgb): string {
if (typeof color === "number") {
return run(
str,
code(
[38, 2, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff],
39,
),
);
}
return run(
str,
code(
[
38,
2,
clampAndTruncate(color.r),
clampAndTruncate(color.g),
clampAndTruncate(color.b),
],
39,
),
);
}
/**
* Set background color using 24bit rgb.
* `color` can be a number in range `0x000000` to `0xffffff` or
* an `Rgb`.
*
* To produce the color magenta:
*
* bgRgb24("foo", 0xff00ff);
* bgRgb24("foo", {r: 255, g: 0, b: 255});
* @param str text color to apply 24bit rgb to
* @param color code
*/
export function bgRgb24(str: string, color: number | Rgb): string {
if (typeof color === "number") {
return run(
str,
code(
[48, 2, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff],
49,
),
);
}
return run(
str,
code(
[
48,
2,
clampAndTruncate(color.r),
clampAndTruncate(color.g),
clampAndTruncate(color.b),
],
49,
),
);
}
// https://github.com/chalk/ansi-regex/blob/2b56fb0c7a07108e5b54241e8faec160d393aedb/index.js
const ANSI_PATTERN = new RegExp(
[
"[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)",
"(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))",
].join("|"),
"g",
);
/**
* Remove ANSI escape codes from the string.
* @param string to remove ANSI escape codes from
*/
export function stripColor(string: string): string {
return string.replace(ANSI_PATTERN, "");
}

View file

@ -1,16 +0,0 @@
{
"headers": {
"content-length": "11645",
"server": "AmazonS3",
"last-modified": "Mon, 23 Aug 2021 22:19:13 GMT",
"cache-control": "public, max-age=31536000, immutable",
"x-amz-id-2": "FbRGxGOy9wqib+2NQ1OVOixb8qUPq0K2NDOPKeiteZLBpxlPowodpk7eXK5IMA4skwcEmKpYG4A=",
"access-control-allow-origin": "*",
"content-type": "application/typescript; charset=utf-8",
"date": "Tue, 24 Aug 2021 13:53:42 GMT",
"x-amz-request-id": "5WK83W9VC1FTCG2T",
"x-amz-version-id": "kBd3kTxoXIUIFIrZfyw68XCGEhqwG0Jq",
"etag": "\"5450ef49e6252532f88e69f2c194528a\""
},
"url": "https://deno.land/std@0.106.0/fmt/colors.ts"
}

View file

@ -1,339 +0,0 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
// This module is browser compatible.
interface FarthestPoint {
y: number;
id: number;
}
export enum DiffType {
removed = "removed",
common = "common",
added = "added",
}
export interface DiffResult<T> {
type: DiffType;
value: T;
details?: Array<DiffResult<T>>;
}
const REMOVED = 1;
const COMMON = 2;
const ADDED = 3;
function createCommon<T>(A: T[], B: T[], reverse?: boolean): T[] {
const common = [];
if (A.length === 0 || B.length === 0) return [];
for (let i = 0; i < Math.min(A.length, B.length); i += 1) {
if (
A[reverse ? A.length - i - 1 : i] === B[reverse ? B.length - i - 1 : i]
) {
common.push(A[reverse ? A.length - i - 1 : i]);
} else {
return common;
}
}
return common;
}
/**
* Renders the differences between the actual and expected values
* @param A Actual value
* @param B Expected value
*/
export function diff<T>(A: T[], B: T[]): Array<DiffResult<T>> {
const prefixCommon = createCommon(A, B);
const suffixCommon = createCommon(
A.slice(prefixCommon.length),
B.slice(prefixCommon.length),
true,
).reverse();
A = suffixCommon.length
? A.slice(prefixCommon.length, -suffixCommon.length)
: A.slice(prefixCommon.length);
B = suffixCommon.length
? B.slice(prefixCommon.length, -suffixCommon.length)
: B.slice(prefixCommon.length);
const swapped = B.length > A.length;
[A, B] = swapped ? [B, A] : [A, B];
const M = A.length;
const N = B.length;
if (!M && !N && !suffixCommon.length && !prefixCommon.length) return [];
if (!N) {
return [
...prefixCommon.map(
(c): DiffResult<typeof c> => ({ type: DiffType.common, value: c }),
),
...A.map(
(a): DiffResult<typeof a> => ({
type: swapped ? DiffType.added : DiffType.removed,
value: a,
}),
),
...suffixCommon.map(
(c): DiffResult<typeof c> => ({ type: DiffType.common, value: c }),
),
];
}
const offset = N;
const delta = M - N;
const size = M + N + 1;
const fp = new Array(size).fill({ y: -1 });
/**
* INFO:
* This buffer is used to save memory and improve performance.
* The first half is used to save route and last half is used to save diff
* type.
* This is because, when I kept new uint8array area to save type,performance
* worsened.
*/
const routes = new Uint32Array((M * N + size + 1) * 2);
const diffTypesPtrOffset = routes.length / 2;
let ptr = 0;
let p = -1;
function backTrace<T>(
A: T[],
B: T[],
current: FarthestPoint,
swapped: boolean,
): Array<{
type: DiffType;
value: T;
}> {
const M = A.length;
const N = B.length;
const result = [];
let a = M - 1;
let b = N - 1;
let j = routes[current.id];
let type = routes[current.id + diffTypesPtrOffset];
while (true) {
if (!j && !type) break;
const prev = j;
if (type === REMOVED) {
result.unshift({
type: swapped ? DiffType.removed : DiffType.added,
value: B[b],
});
b -= 1;
} else if (type === ADDED) {
result.unshift({
type: swapped ? DiffType.added : DiffType.removed,
value: A[a],
});
a -= 1;
} else {
result.unshift({ type: DiffType.common, value: A[a] });
a -= 1;
b -= 1;
}
j = routes[prev];
type = routes[prev + diffTypesPtrOffset];
}
return result;
}
function createFP(
slide: FarthestPoint,
down: FarthestPoint,
k: number,
M: number,
): FarthestPoint {
if (slide && slide.y === -1 && down && down.y === -1) {
return { y: 0, id: 0 };
}
if (
(down && down.y === -1) ||
k === M ||
(slide && slide.y) > (down && down.y) + 1
) {
const prev = slide.id;
ptr++;
routes[ptr] = prev;
routes[ptr + diffTypesPtrOffset] = ADDED;
return { y: slide.y, id: ptr };
} else {
const prev = down.id;
ptr++;
routes[ptr] = prev;
routes[ptr + diffTypesPtrOffset] = REMOVED;
return { y: down.y + 1, id: ptr };
}
}
function snake<T>(
k: number,
slide: FarthestPoint,
down: FarthestPoint,
_offset: number,
A: T[],
B: T[],
): FarthestPoint {
const M = A.length;
const N = B.length;
if (k < -N || M < k) return { y: -1, id: -1 };
const fp = createFP(slide, down, k, M);
while (fp.y + k < M && fp.y < N && A[fp.y + k] === B[fp.y]) {
const prev = fp.id;
ptr++;
fp.id = ptr;
fp.y += 1;
routes[ptr] = prev;
routes[ptr + diffTypesPtrOffset] = COMMON;
}
return fp;
}
while (fp[delta + offset].y < N) {
p = p + 1;
for (let k = -p; k < delta; ++k) {
fp[k + offset] = snake(
k,
fp[k - 1 + offset],
fp[k + 1 + offset],
offset,
A,
B,
);
}
for (let k = delta + p; k > delta; --k) {
fp[k + offset] = snake(
k,
fp[k - 1 + offset],
fp[k + 1 + offset],
offset,
A,
B,
);
}
fp[delta + offset] = snake(
delta,
fp[delta - 1 + offset],
fp[delta + 1 + offset],
offset,
A,
B,
);
}
return [
...prefixCommon.map(
(c): DiffResult<typeof c> => ({ type: DiffType.common, value: c }),
),
...backTrace(A, B, fp[delta + offset], swapped),
...suffixCommon.map(
(c): DiffResult<typeof c> => ({ type: DiffType.common, value: c }),
),
];
}
/**
* Renders the differences between the actual and expected strings
* Partially inspired from https://github.com/kpdecker/jsdiff
* @param A Actual string
* @param B Expected string
*/
export function diffstr(A: string, B: string) {
function tokenize(string: string, { wordDiff = false } = {}): string[] {
if (wordDiff) {
// Split string on whitespace symbols
const tokens = string.split(/([^\S\r\n]+|[()[\]{}'"\r\n]|\b)/);
// Extended Latin character set
const words =
/^[a-zA-Z\u{C0}-\u{FF}\u{D8}-\u{F6}\u{F8}-\u{2C6}\u{2C8}-\u{2D7}\u{2DE}-\u{2FF}\u{1E00}-\u{1EFF}]+$/u;
// Join boundary splits that we do not consider to be boundaries and merge empty strings surrounded by word chars
for (let i = 0; i < tokens.length - 1; i++) {
if (
!tokens[i + 1] && tokens[i + 2] && words.test(tokens[i]) &&
words.test(tokens[i + 2])
) {
tokens[i] += tokens[i + 2];
tokens.splice(i + 1, 2);
i--;
}
}
return tokens.filter((token) => token);
} else {
// Split string on new lines symbols
const tokens = [], lines = string.split(/(\n|\r\n)/);
// Ignore final empty token when text ends with a newline
if (!lines[lines.length - 1]) {
lines.pop();
}
// Merge the content and line separators into single tokens
for (let i = 0; i < lines.length; i++) {
if (i % 2) {
tokens[tokens.length - 1] += lines[i];
} else {
tokens.push(lines[i]);
}
}
return tokens;
}
}
// Create details by filtering revelant word-diff for current line
// and merge "space-diff" if surrounded by word-diff for cleaner displays
function createDetails(
line: DiffResult<string>,
tokens: Array<DiffResult<string>>,
) {
return tokens.filter(({ type }) =>
type === line.type || type === DiffType.common
).map((result, i, t) => {
if (
(result.type === DiffType.common) && (t[i - 1]) &&
(t[i - 1]?.type === t[i + 1]?.type) && /\s+/.test(result.value)
) {
result.type = t[i - 1].type;
}
return result;
});
}
// Compute multi-line diff
const diffResult = diff(tokenize(`${A}\n`), tokenize(`${B}\n`));
const added = [], removed = [];
for (const result of diffResult) {
if (result.type === DiffType.added) {
added.push(result);
}
if (result.type === DiffType.removed) {
removed.push(result);
}
}
// Compute word-diff
const aLines = added.length < removed.length ? added : removed;
const bLines = aLines === removed ? added : removed;
for (const a of aLines) {
let tokens = [] as Array<DiffResult<string>>,
b: undefined | DiffResult<string>;
// Search another diff line with at least one common token
while (bLines.length) {
b = bLines.shift();
tokens = diff(
tokenize(a.value, { wordDiff: true }),
tokenize(b?.value ?? "", { wordDiff: true }),
);
if (
tokens.some(({ type, value }) =>
type === DiffType.common && value.trim().length
)
) {
break;
}
}
// Register word-diff details
a.details = createDetails(a, tokens);
if (b) {
b.details = createDetails(b, tokens);
}
}
return diffResult;
}

View file

@ -1,16 +0,0 @@
{
"headers": {
"cache-control": "public, max-age=31536000, immutable",
"x-amz-request-id": "5WK6KHYNZZ5KA6AY",
"content-length": "8987",
"content-type": "application/typescript; charset=utf-8",
"etag": "\"cf6aa0f0d1f64e912327dd59540f2c89\"",
"server": "AmazonS3",
"x-amz-id-2": "RQLaFsC0gkZeP3osZE1P0ryyqAJvZzkiEUdemkaCkZe9kbozl8/YSR0E9GpLoNcZD9GrYuowmaA=",
"date": "Tue, 24 Aug 2021 13:53:42 GMT",
"x-amz-version-id": "s.ztI5zs1eOnsBLULnHd3GCV8eow4WNa",
"last-modified": "Mon, 23 Aug 2021 22:19:15 GMT",
"access-control-allow-origin": "*"
},
"url": "https://deno.land/std@0.106.0/testing/_diff.ts"
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
{"version_hash":"b9fc019860293cf104762ad4848e398e54835bf27d222c327c59b9350664a519"}

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
{"version_hash":"9afb5f692fc2cd52a9b45d2dadc1c6878dadc24036e58736e00585a97211b0c4"}

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
{"version_hash":"48aa556daec2980127ca50aa078501e880d5118fe3045ea105f4c64fd72f1deb"}