summaryrefslogtreecommitdiff
path: root/std/fmt
diff options
context:
space:
mode:
Diffstat (limited to 'std/fmt')
-rw-r--r--std/fmt/README.md240
-rw-r--r--std/fmt/TODO13
-rw-r--r--std/fmt/colors.ts522
-rw-r--r--std/fmt/colors_test.ts230
-rw-r--r--std/fmt/printf.ts757
-rw-r--r--std/fmt/printf_test.ts674
6 files changed, 0 insertions, 2436 deletions
diff --git a/std/fmt/README.md b/std/fmt/README.md
deleted file mode 100644
index 8c44d78a7..000000000
--- a/std/fmt/README.md
+++ /dev/null
@@ -1,240 +0,0 @@
-# Printf for Deno
-
-This is very much a work-in-progress. I'm actively soliciting feedback. What
-immediately follows are points for discussion.
-
-If you are looking for the documentation proper, skip to:
-
- "printf: prints formatted output"
-
-and
-
- "Colors"
-
-below.
-
-## Discussion
-
-This is very much a work-in-progress. I'm actively soliciting feedback.
-
-- What useful features are available in other languages apart from Golang and C?
-
-- behaviour of `%v` verb. In Golang, this is a shortcut verb to "print the
- default format" of the argument. It is currently implemented to format using
- `toString` in the default case and `inspect` if the `%#v` alternative format
- flag is used in the format directive. Alternatively, `%V` could be used to
- distinguish the two.
-
- `inspect` output is not defined, however. This may be problematic if using
- this code on other platforms (and expecting interoperability). To my
- knowledge, no suitable specification of object representation aside from JSON
- and `toString` exist. ( Aside: see "[Common object formats][3]" in the
- "Console Living Standard" which basically says "do whatever" )
-
-- `%j` verb. This is an extension particular to this implementation. Currently
- not very sophisticated, it just runs `JSON.stringify` on the argument.
- Consider possible modifier flags, etc.
-
-- `<` verb. This is an extension that assumes the argument is an array and will
- format each element according to the format (surrounded by [] and separated by
- comma) (`<` Mnemonic: pull each element out of array)
-
-- how to deal with more newfangled JavaScript features (generic Iterables, Map
- and Set types, typed Arrays, ...)
-
-- the implementation is fairly rough around the edges:
-
-- currently contains little in the way of checking for correctness. Conceivably,
- there will be a 'strict' form, e.g. that ensures only Number-ish arguments are
- passed to %f flags.
-
-- assembles output using string concatenation instead of utilizing buffers or
- other optimizations. It would be nice to have printf / sprintf / fprintf (etc)
- all in one.
-
-- float formatting is handled by toString() and to `toExponential` along with a
- mess of Regexp. Would be nice to use fancy match.
-
-- some flags that are potentially applicable ( POSIX long and unsigned modifiers
- are not likely useful) are missing, namely %q (print quoted), %U (unicode
- format)
-
-# printf: prints formatted output
-
-sprintf converts and formats a variable number of arguments as is specified by a
-`format string`. In it's basic form, a format string may just be a literal. In
-case arguments are meant to be formatted, a `directive` is contained in the
-format string, preceded by a '%' character:
-
- %<verb>
-
-E.g. the verb `s` indicates the directive should be replaced by the string
-representation of the argument in the corresponding position of the argument
-list. E.g.:
-
- Hello %s!
-
-applied to the arguments "World" yields "Hello World!".
-
-The meaning of the format string is modelled after [POSIX][1] format strings as
-well as well as [Golang format strings][2]. Both contain elements specific to
-the respective programming language that don't apply to JavaScript, so they can
-not be fully supported. Furthermore we implement some functionality that is
-specific to JS.
-
-## Verbs
-
-The following verbs are supported:
-
-| Verb | Meaning |
-| ----- | -------------------------------------------------------------- |
-| `%` | print a literal percent |
-| `t` | evaluate arg as boolean, print `true` or `false` |
-| `b` | eval as number, print binary |
-| `c` | eval as number, print character corresponding to the codePoint |
-| `o` | eval as number, print octal |
-| `x X` | print as hex (ff FF), treat string as list of bytes |
-| `e E` | print number in scientific/exponent format 1.123123e+01 |
-| `f F` | print number as float with decimal point and no exponent |
-| `g G` | use %e %E or %f %F depending on size of argument |
-| `s` | interpolate string |
-| `T` | type of arg, as returned by `typeof` |
-| `v` | value of argument in 'default' format (see below) |
-| `j` | argument as formatted by `JSON.stringify` |
-
-## Width and Precision
-
-Verbs may be modified by providing them with width and precision, either or both
-may be omitted:
-
- %9f width 9, default precision
- %.9f default width, precision 9
- %8.9f width 8, precision 9
- %8.f width 9, precision 0
-
-In general, 'width' describes the minimum length of the output, while
-'precision' limits the output.
-
-| verb | precision |
-| --------- | --------------------------------------------------------------- |
-| `t` | n/a |
-| `b c o` | n/a |
-| `x X` | n/a for number, strings are truncated to p bytes(!) |
-| `e E f F` | number of places after decimal, default 6 |
-| `g G` | set maximum number of digits |
-| `s` | truncate input |
-| `T` | truncate |
-| `v` | truncate, or depth if used with # see "'default' format", below |
-| `j` | n/a |
-
-Numerical values for width and precision can be substituted for the `*` char, in
-which case the values are obtained from the next args, e.g.:
-
- sprintf("%*.*f", 9, 8, 456.0)
-
-is equivalent to:
-
- sprintf("%9.8f", 456.0)
-
-## Flags
-
-The effects of the verb may be further influenced by using flags to modify the
-directive:
-
-| Flag | Verb | Meaning |
-| ----- | --------- | -------------------------------------------------------------------------- |
-| `+` | numeric | always print sign |
-| `-` | all | pad to the right (left justify) |
-| `#` | | alternate format |
-| `#` | `b o x X` | prefix with `0b 0 0x` |
-| `#` | `g G` | don't remove trailing zeros |
-| `#` | `v` | ues output of `inspect` instead of `toString` |
-| `' '` | | space character |
-| `' '` | `x X` | leave spaces between bytes when printing string |
-| `' '` | `d` | insert space for missing `+` sign character |
-| `0` | all | pad with zero, `-` takes precedence, sign is appended in front of padding |
-| `<` | all | format elements of the passed array according to the directive (extension) |
-
-## 'default' format
-
-The default format used by `%v` is the result of calling `toString()` on the
-relevant argument. If the `#` flags is used, the result of calling `inspect()`
-is interpolated. In this case, the precision, if set is passed to `inspect()` as
-the 'depth' config parameter.
-
-## Positional arguments
-
-Arguments do not need to be consumed in the order they are provided and may be
-consumed more than once. E.g.:
-
- sprintf("%[2]s %[1]s", "World", "Hello")
-
-returns "Hello World". The presence of a positional indicator resets the arg
-counter allowing args to be reused:
-
- sprintf("dec[%d]=%d hex[%[1]d]=%x oct[%[1]d]=%#o %s", 1, 255, "Third")
-
-returns `dec[1]=255 hex[1]=0xff oct[1]=0377 Third`
-
-Width and precision my also use positionals:
-
- "%[2]*.[1]*d", 1, 2
-
-This follows the golang conventions and not POSIX.
-
-## Errors
-
-The following errors are handled:
-
-Incorrect verb:
-
- S("%h", "") %!(BAD VERB 'h')
-
-Too few arguments:
-
- S("%d") %!(MISSING 'd')"
-
-# Colors
-
-Adds functions used for displaying colored text.
-
-## Usage
-
-```typescript
-import {
- bgBlue,
- bgRgb24,
- bgRgb8,
- bold,
- italic,
- red,
- rgb24,
- rgb8,
-} from "https://deno.land/std@$STD_VERSION/fmt/colors.ts";
-
-console.log(bgBlue(italic(red(bold("Hello, World!")))));
-
-// also supports 8bit colors
-
-console.log(rgb8("Hello, World!", 42));
-
-console.log(bgRgb8("Hello, World!", 42));
-
-// and 24bit rgb
-
-console.log(rgb24("Hello, World!", {
- r: 41,
- g: 42,
- b: 43,
-}));
-
-console.log(bgRgb24("Hello, World!", {
- r: 41,
- g: 42,
- b: 43,
-}));
-```
-
-[1]: https://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html
-[2]: https://golang.org/pkg/fmt/
-[3]: https://console.spec.whatwg.org/#object-formats
diff --git a/std/fmt/TODO b/std/fmt/TODO
deleted file mode 100644
index 7f95c7a78..000000000
--- a/std/fmt/TODO
+++ /dev/null
@@ -1,13 +0,0 @@
-
-* "native" formatting, json, arrays, object/structs, functions ...
-* %q %U
-* Java has a %n flag to print the platform native newline... in POSIX
- that means "number of chars printed so far", though.
-* Use of Writer and Buffer internally in order to make fprintf, printf, etc.
- easier and more elegant.
-
-* See "Discussion" in README
-
-* scanf, pack, unpack, annotated hex
-* Consistent error handling.
-* Rewrite (probably), now that I know how it's done.
diff --git a/std/fmt/colors.ts b/std/fmt/colors.ts
deleted file mode 100644
index 3596638f5..000000000
--- a/std/fmt/colors.ts
+++ /dev/null
@@ -1,522 +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.
-
-const noColor = globalThis.Deno?.noColor ?? 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:
- *
- * rgba24("foo", 0xff00ff);
- * rgba24("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:
- *
- * bgRgba24("foo", 0xff00ff);
- * bgRgba24("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, "");
-}
diff --git a/std/fmt/colors_test.ts b/std/fmt/colors_test.ts
deleted file mode 100644
index 7f5940a4d..000000000
--- a/std/fmt/colors_test.ts
+++ /dev/null
@@ -1,230 +0,0 @@
-// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-import { assertEquals } from "../testing/asserts.ts";
-import * as c from "./colors.ts";
-import "../examples/colors.ts";
-
-Deno.test("singleColor", function (): void {
- assertEquals(c.red("foo bar"), "foo bar");
-});
-
-Deno.test("doubleColor", function (): void {
- assertEquals(c.bgBlue(c.red("foo bar")), "foo bar");
-});
-
-Deno.test("replacesCloseCharacters", function (): void {
- assertEquals(c.red("Hello"), "Hello");
-});
-
-Deno.test("enablingColors", function (): void {
- assertEquals(c.getColorEnabled(), true);
- c.setColorEnabled(false);
- assertEquals(c.bgBlue(c.red("foo bar")), "foo bar");
- c.setColorEnabled(true);
- assertEquals(c.red("foo bar"), "foo bar");
-});
-
-Deno.test("testBold", function (): void {
- assertEquals(c.bold("foo bar"), "foo bar");
-});
-
-Deno.test("testDim", function (): void {
- assertEquals(c.dim("foo bar"), "foo bar");
-});
-
-Deno.test("testItalic", function (): void {
- assertEquals(c.italic("foo bar"), "foo bar");
-});
-
-Deno.test("testUnderline", function (): void {
- assertEquals(c.underline("foo bar"), "foo bar");
-});
-
-Deno.test("testInverse", function (): void {
- assertEquals(c.inverse("foo bar"), "foo bar");
-});
-
-Deno.test("testHidden", function (): void {
- assertEquals(c.hidden("foo bar"), "foo bar");
-});
-
-Deno.test("testStrikethrough", function (): void {
- assertEquals(c.strikethrough("foo bar"), "foo bar");
-});
-
-Deno.test("testBlack", function (): void {
- assertEquals(c.black("foo bar"), "foo bar");
-});
-
-Deno.test("testRed", function (): void {
- assertEquals(c.red("foo bar"), "foo bar");
-});
-
-Deno.test("testGreen", function (): void {
- assertEquals(c.green("foo bar"), "foo bar");
-});
-
-Deno.test("testYellow", function (): void {
- assertEquals(c.yellow("foo bar"), "foo bar");
-});
-
-Deno.test("testBlue", function (): void {
- assertEquals(c.blue("foo bar"), "foo bar");
-});
-
-Deno.test("testMagenta", function (): void {
- assertEquals(c.magenta("foo bar"), "foo bar");
-});
-
-Deno.test("testCyan", function (): void {
- assertEquals(c.cyan("foo bar"), "foo bar");
-});
-
-Deno.test("testWhite", function (): void {
- assertEquals(c.white("foo bar"), "foo bar");
-});
-
-Deno.test("testGray", function (): void {
- assertEquals(c.gray("foo bar"), "foo bar");
-});
-
-Deno.test("testBrightBlack", function (): void {
- assertEquals(c.brightBlack("foo bar"), "foo bar");
-});
-
-Deno.test("testBrightRed", function (): void {
- assertEquals(c.brightRed("foo bar"), "foo bar");
-});
-
-Deno.test("testBrightGreen", function (): void {
- assertEquals(c.brightGreen("foo bar"), "foo bar");
-});
-
-Deno.test("testBrightYellow", function (): void {
- assertEquals(c.brightYellow("foo bar"), "foo bar");
-});
-
-Deno.test("testBrightBlue", function (): void {
- assertEquals(c.brightBlue("foo bar"), "foo bar");
-});
-
-Deno.test("testBrightMagenta", function (): void {
- assertEquals(c.brightMagenta("foo bar"), "foo bar");
-});
-
-Deno.test("testBrightCyan", function (): void {
- assertEquals(c.brightCyan("foo bar"), "foo bar");
-});
-
-Deno.test("testBrightWhite", function (): void {
- assertEquals(c.brightWhite("foo bar"), "foo bar");
-});
-
-Deno.test("testBgBlack", function (): void {
- assertEquals(c.bgBlack("foo bar"), "foo bar");
-});
-
-Deno.test("testBgRed", function (): void {
- assertEquals(c.bgRed("foo bar"), "foo bar");
-});
-
-Deno.test("testBgGreen", function (): void {
- assertEquals(c.bgGreen("foo bar"), "foo bar");
-});
-
-Deno.test("testBgYellow", function (): void {
- assertEquals(c.bgYellow("foo bar"), "foo bar");
-});
-
-Deno.test("testBgBlue", function (): void {
- assertEquals(c.bgBlue("foo bar"), "foo bar");
-});
-
-Deno.test("testBgMagenta", function (): void {
- assertEquals(c.bgMagenta("foo bar"), "foo bar");
-});
-
-Deno.test("testBgCyan", function (): void {
- assertEquals(c.bgCyan("foo bar"), "foo bar");
-});
-
-Deno.test("testBgWhite", function (): void {
- assertEquals(c.bgWhite("foo bar"), "foo bar");
-});
-
-Deno.test("testBgBrightBlack", function (): void {
- assertEquals(c.bgBrightBlack("foo bar"), "foo bar");
-});
-
-Deno.test("testBgBrightRed", function (): void {
- assertEquals(c.bgBrightRed("foo bar"), "foo bar");
-});
-
-Deno.test("testBgBrightGreen", function (): void {
- assertEquals(c.bgBrightGreen("foo bar"), "foo bar");
-});
-
-Deno.test("testBgBrightYellow", function (): void {
- assertEquals(c.bgBrightYellow("foo bar"), "foo bar");
-});
-
-Deno.test("testBgBrightBlue", function (): void {
- assertEquals(c.bgBrightBlue("foo bar"), "foo bar");
-});
-
-Deno.test("testBgBrightMagenta", function (): void {
- assertEquals(c.bgBrightMagenta("foo bar"), "foo bar");
-});
-
-Deno.test("testBgBrightCyan", function (): void {
- assertEquals(c.bgBrightCyan("foo bar"), "foo bar");
-});
-
-Deno.test("testBgBrightWhite", function (): void {
- assertEquals(c.bgBrightWhite("foo bar"), "foo bar");
-});
-
-Deno.test("testClampUsingRgb8", function (): void {
- assertEquals(c.rgb8("foo bar", -10), "foo bar");
-});
-
-Deno.test("testTruncateUsingRgb8", function (): void {
- assertEquals(c.rgb8("foo bar", 42.5), "foo bar");
-});
-
-Deno.test("testRgb8", function (): void {
- assertEquals(c.rgb8("foo bar", 42), "foo bar");
-});
-
-Deno.test("test_bgRgb8", function (): void {
- assertEquals(c.bgRgb8("foo bar", 42), "foo bar");
-});
-
-Deno.test("test_rgb24", function (): void {
- assertEquals(
- c.rgb24("foo bar", {
- r: 41,
- g: 42,
- b: 43,
- }),
- "foo bar",
- );
-});
-
-Deno.test("test_rgb24number", function (): void {
- assertEquals(c.rgb24("foo bar", 0x070809), "foo bar");
-});
-
-Deno.test("test_bgRgb24", function (): void {
- assertEquals(
- c.bgRgb24("foo bar", {
- r: 41,
- g: 42,
- b: 43,
- }),
- "foo bar",
- );
-});
-
-Deno.test("test_bgRgb24number", function (): void {
- assertEquals(c.bgRgb24("foo bar", 0x070809), "foo bar");
-});
diff --git a/std/fmt/printf.ts b/std/fmt/printf.ts
deleted file mode 100644
index 6a821f208..000000000
--- a/std/fmt/printf.ts
+++ /dev/null
@@ -1,757 +0,0 @@
-// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-/**
- * This implementation is inspired by POSIX and Golang but does not port
- * implementation code. */
-
-enum State {
- PASSTHROUGH,
- PERCENT,
- POSITIONAL,
- PRECISION,
- WIDTH,
-}
-
-enum WorP {
- WIDTH,
- PRECISION,
-}
-
-class Flags {
- plus?: boolean;
- dash?: boolean;
- sharp?: boolean;
- space?: boolean;
- zero?: boolean;
- lessthan?: boolean;
- width = -1;
- precision = -1;
-}
-
-const min = Math.min;
-const UNICODE_REPLACEMENT_CHARACTER = "\ufffd";
-const DEFAULT_PRECISION = 6;
-const FLOAT_REGEXP = /(-?)(\d)\.?(\d*)e([+-])(\d+)/;
-
-enum F {
- sign = 1,
- mantissa,
- fractional,
- esign,
- exponent,
-}
-
-class Printf {
- format: string;
- args: unknown[];
- i: number;
-
- state: State = State.PASSTHROUGH;
- verb = "";
- buf = "";
- argNum = 0;
- flags: Flags = new Flags();
-
- haveSeen: boolean[];
-
- // barf, store precision and width errors for later processing ...
- tmpError?: string;
-
- constructor(format: string, ...args: unknown[]) {
- this.format = format;
- this.args = args;
- this.haveSeen = new Array(args.length);
- this.i = 0;
- }
-
- doPrintf(): string {
- for (; this.i < this.format.length; ++this.i) {
- const c = this.format[this.i];
- switch (this.state) {
- case State.PASSTHROUGH:
- if (c === "%") {
- this.state = State.PERCENT;
- } else {
- this.buf += c;
- }
- break;
- case State.PERCENT:
- if (c === "%") {
- this.buf += c;
- this.state = State.PASSTHROUGH;
- } else {
- this.handleFormat();
- }
- break;
- default:
- throw Error("Should be unreachable, certainly a bug in the lib.");
- }
- }
- // check for unhandled args
- let extras = false;
- let err = "%!(EXTRA";
- for (let i = 0; i !== this.haveSeen.length; ++i) {
- if (!this.haveSeen[i]) {
- extras = true;
- err += ` '${Deno.inspect(this.args[i])}'`;
- }
- }
- err += ")";
- if (extras) {
- this.buf += err;
- }
- return this.buf;
- }
-
- // %[<positional>]<flag>...<verb>
- handleFormat(): void {
- this.flags = new Flags();
- const flags = this.flags;
- for (; this.i < this.format.length; ++this.i) {
- const c = this.format[this.i];
- switch (this.state) {
- case State.PERCENT:
- switch (c) {
- case "[":
- this.handlePositional();
- this.state = State.POSITIONAL;
- break;
- case "+":
- flags.plus = true;
- break;
- case "<":
- flags.lessthan = true;
- break;
- case "-":
- flags.dash = true;
- flags.zero = false; // only left pad zeros, dash takes precedence
- break;
- case "#":
- flags.sharp = true;
- break;
- case " ":
- flags.space = true;
- break;
- case "0":
- // only left pad zeros, dash takes precedence
- flags.zero = !flags.dash;
- break;
- default:
- if (("1" <= c && c <= "9") || c === "." || c === "*") {
- if (c === ".") {
- this.flags.precision = 0;
- this.state = State.PRECISION;
- this.i++;
- } else {
- this.state = State.WIDTH;
- }
- this.handleWidthAndPrecision(flags);
- } else {
- this.handleVerb();
- return; // always end in verb
- }
- } // switch c
- break;
- case State.POSITIONAL:
- // TODO(bartlomieju): either a verb or * only verb for now
- if (c === "*") {
- const worp = this.flags.precision === -1
- ? WorP.WIDTH
- : WorP.PRECISION;
- this.handleWidthOrPrecisionRef(worp);
- this.state = State.PERCENT;
- break;
- } else {
- this.handleVerb();
- return; // always end in verb
- }
- default:
- throw new Error(`Should not be here ${this.state}, library bug!`);
- } // switch state
- }
- }
-
- /**
- * Handle width or precision
- * @param wOrP
- */
- handleWidthOrPrecisionRef(wOrP: WorP): void {
- if (this.argNum >= this.args.length) {
- // handle Positional should have already taken care of it...
- return;
- }
- const arg = this.args[this.argNum];
- this.haveSeen[this.argNum] = true;
- if (typeof arg === "number") {
- switch (wOrP) {
- case WorP.WIDTH:
- this.flags.width = arg;
- break;
- default:
- this.flags.precision = arg;
- }
- } else {
- const tmp = wOrP === WorP.WIDTH ? "WIDTH" : "PREC";
- this.tmpError = `%!(BAD ${tmp} '${this.args[this.argNum]}')`;
- }
- this.argNum++;
- }
-
- /**
- * Handle width and precision
- * @param flags
- */
- handleWidthAndPrecision(flags: Flags): void {
- const fmt = this.format;
- for (; this.i !== this.format.length; ++this.i) {
- const c = fmt[this.i];
- switch (this.state) {
- case State.WIDTH:
- switch (c) {
- case ".":
- // initialize precision, %9.f -> precision=0
- this.flags.precision = 0;
- this.state = State.PRECISION;
- break;
- case "*":
- this.handleWidthOrPrecisionRef(WorP.WIDTH);
- // force . or flag at this point
- break;
- default: {
- const val = parseInt(c);
- // most likely parseInt does something stupid that makes
- // it unusable for this scenario ...
- // if we encounter a non (number|*|.) we're done with prec & wid
- if (isNaN(val)) {
- this.i--;
- this.state = State.PERCENT;
- return;
- }
- flags.width = flags.width == -1 ? 0 : flags.width;
- flags.width *= 10;
- flags.width += val;
- }
- } // switch c
- break;
- case State.PRECISION: {
- if (c === "*") {
- this.handleWidthOrPrecisionRef(WorP.PRECISION);
- break;
- }
- const val = parseInt(c);
- if (isNaN(val)) {
- // one too far, rewind
- this.i--;
- this.state = State.PERCENT;
- return;
- }
- flags.precision *= 10;
- flags.precision += val;
- break;
- }
- default:
- throw new Error("can't be here. bug.");
- } // switch state
- }
- }
-
- /** Handle positional */
- handlePositional(): void {
- if (this.format[this.i] !== "[") {
- // sanity only
- throw new Error("Can't happen? Bug.");
- }
- let positional = 0;
- const format = this.format;
- this.i++;
- let err = false;
- for (; this.i !== this.format.length; ++this.i) {
- if (format[this.i] === "]") {
- break;
- }
- positional *= 10;
- const val = parseInt(format[this.i]);
- if (isNaN(val)) {
- //throw new Error(
- // `invalid character in positional: ${format}[${format[this.i]}]`
- //);
- this.tmpError = "%!(BAD INDEX)";
- err = true;
- }
- positional += val;
- }
- if (positional - 1 >= this.args.length) {
- this.tmpError = "%!(BAD INDEX)";
- err = true;
- }
- this.argNum = err ? this.argNum : positional - 1;
- return;
- }
-
- /** Handle less than */
- handleLessThan(): string {
- // deno-lint-ignore no-explicit-any
- const arg = this.args[this.argNum] as any;
- if ((arg || {}).constructor.name !== "Array") {
- throw new Error(`arg ${arg} is not an array. Todo better error handling`);
- }
- let str = "[ ";
- for (let i = 0; i !== arg.length; ++i) {
- if (i !== 0) str += ", ";
- str += this._handleVerb(arg[i]);
- }
- return str + " ]";
- }
-
- /** Handle verb */
- handleVerb(): void {
- const verb = this.format[this.i];
- this.verb = verb;
- if (this.tmpError) {
- this.buf += this.tmpError;
- this.tmpError = undefined;
- if (this.argNum < this.haveSeen.length) {
- this.haveSeen[this.argNum] = true; // keep track of used args
- }
- } else if (this.args.length <= this.argNum) {
- this.buf += `%!(MISSING '${verb}')`;
- } else {
- const arg = this.args[this.argNum]; // check out of range
- this.haveSeen[this.argNum] = true; // keep track of used args
- if (this.flags.lessthan) {
- this.buf += this.handleLessThan();
- } else {
- this.buf += this._handleVerb(arg);
- }
- }
- this.argNum++; // if there is a further positional, it will reset.
- this.state = State.PASSTHROUGH;
- }
-
- // deno-lint-ignore no-explicit-any
- _handleVerb(arg: any): string {
- switch (this.verb) {
- case "t":
- return this.pad(arg.toString());
- case "b":
- return this.fmtNumber(arg as number, 2);
- case "c":
- return this.fmtNumberCodePoint(arg as number);
- case "d":
- return this.fmtNumber(arg as number, 10);
- case "o":
- return this.fmtNumber(arg as number, 8);
- case "x":
- return this.fmtHex(arg);
- case "X":
- return this.fmtHex(arg, true);
- case "e":
- return this.fmtFloatE(arg as number);
- case "E":
- return this.fmtFloatE(arg as number, true);
- case "f":
- case "F":
- return this.fmtFloatF(arg as number);
- case "g":
- return this.fmtFloatG(arg as number);
- case "G":
- return this.fmtFloatG(arg as number, true);
- case "s":
- return this.fmtString(arg as string);
- case "T":
- return this.fmtString(typeof arg);
- case "v":
- return this.fmtV(arg);
- case "j":
- return this.fmtJ(arg);
- default:
- return `%!(BAD VERB '${this.verb}')`;
- }
- }
-
- /**
- * Pad a string
- * @param s text to pad
- */
- pad(s: string): string {
- const padding = this.flags.zero ? "0" : " ";
-
- if (this.flags.dash) {
- return s.padEnd(this.flags.width, padding);
- }
-
- return s.padStart(this.flags.width, padding);
- }
-
- /**
- * Pad a number
- * @param nStr
- * @param neg
- */
- padNum(nStr: string, neg: boolean): string {
- let sign: string;
- if (neg) {
- sign = "-";
- } else if (this.flags.plus || this.flags.space) {
- sign = this.flags.plus ? "+" : " ";
- } else {
- sign = "";
- }
- const zero = this.flags.zero;
- if (!zero) {
- // sign comes in front of padding when padding w/ zero,
- // in from of value if padding with spaces.
- nStr = sign + nStr;
- }
-
- const pad = zero ? "0" : " ";
- const len = zero ? this.flags.width - sign.length : this.flags.width;
-
- if (this.flags.dash) {
- nStr = nStr.padEnd(len, pad);
- } else {
- nStr = nStr.padStart(len, pad);
- }
-
- if (zero) {
- // see above
- nStr = sign + nStr;
- }
- return nStr;
- }
-
- /**
- * Format a number
- * @param n
- * @param radix
- * @param upcase
- */
- fmtNumber(n: number, radix: number, upcase = false): string {
- let num = Math.abs(n).toString(radix);
- const prec = this.flags.precision;
- if (prec !== -1) {
- this.flags.zero = false;
- num = n === 0 && prec === 0 ? "" : num;
- while (num.length < prec) {
- num = "0" + num;
- }
- }
- let prefix = "";
- if (this.flags.sharp) {
- switch (radix) {
- case 2:
- prefix += "0b";
- break;
- case 8:
- // don't annotate octal 0 with 0...
- prefix += num.startsWith("0") ? "" : "0";
- break;
- case 16:
- prefix += "0x";
- break;
- default:
- throw new Error("cannot handle base: " + radix);
- }
- }
- // don't add prefix in front of value truncated by precision=0, val=0
- num = num.length === 0 ? num : prefix + num;
- if (upcase) {
- num = num.toUpperCase();
- }
- return this.padNum(num, n < 0);
- }
-
- /**
- * Format number with code points
- * @param n
- */
- fmtNumberCodePoint(n: number): string {
- let s = "";
- try {
- s = String.fromCodePoint(n);
- } catch (RangeError) {
- s = UNICODE_REPLACEMENT_CHARACTER;
- }
- return this.pad(s);
- }
-
- /**
- * Format special float
- * @param n
- */
- fmtFloatSpecial(n: number): string {
- // formatting of NaN and Inf are pants-on-head
- // stupid and more or less arbitrary.
-
- if (isNaN(n)) {
- this.flags.zero = false;
- return this.padNum("NaN", false);
- }
- if (n === Number.POSITIVE_INFINITY) {
- this.flags.zero = false;
- this.flags.plus = true;
- return this.padNum("Inf", false);
- }
- if (n === Number.NEGATIVE_INFINITY) {
- this.flags.zero = false;
- return this.padNum("Inf", true);
- }
- return "";
- }
-
- /**
- * Round fraction to precision
- * @param fractional
- * @param precision
- */
- roundFractionToPrecision(fractional: string, precision: number): string {
- if (fractional.length > precision) {
- fractional = "1" + fractional; // prepend a 1 in case of leading 0
- let tmp = parseInt(fractional.substr(0, precision + 2)) / 10;
- tmp = Math.round(tmp);
- fractional = Math.floor(tmp).toString();
- fractional = fractional.substr(1); // remove extra 1
- } else {
- while (fractional.length < precision) {
- fractional += "0";
- }
- }
- return fractional;
- }
-
- /**
- * Format float E
- * @param n
- * @param upcase
- */
- fmtFloatE(n: number, upcase = false): string {
- const special = this.fmtFloatSpecial(n);
- if (special !== "") {
- return special;
- }
-
- const m = n.toExponential().match(FLOAT_REGEXP);
- if (!m) {
- throw Error("can't happen, bug");
- }
-
- let fractional = m[F.fractional];
- const precision = this.flags.precision !== -1
- ? this.flags.precision
- : DEFAULT_PRECISION;
- fractional = this.roundFractionToPrecision(fractional, precision);
-
- let e = m[F.exponent];
- // scientific notation output with exponent padded to minlen 2
- e = e.length == 1 ? "0" + e : e;
-
- const val = `${m[F.mantissa]}.${fractional}${upcase ? "E" : "e"}${
- m[F.esign]
- }${e}`;
- return this.padNum(val, n < 0);
- }
-
- /**
- * Format float F
- * @param n
- */
- fmtFloatF(n: number): string {
- const special = this.fmtFloatSpecial(n);
- if (special !== "") {
- return special;
- }
-
- // stupid helper that turns a number into a (potentially)
- // VERY long string.
- function expandNumber(n: number): string {
- if (Number.isSafeInteger(n)) {
- return n.toString() + ".";
- }
-
- const t = n.toExponential().split("e");
- let m = t[0].replace(".", "");
- const e = parseInt(t[1]);
- if (e < 0) {
- let nStr = "0.";
- for (let i = 0; i !== Math.abs(e) - 1; ++i) {
- nStr += "0";
- }
- return (nStr += m);
- } else {
- const splIdx = e + 1;
- while (m.length < splIdx) {
- m += "0";
- }
- return m.substr(0, splIdx) + "." + m.substr(splIdx);
- }
- }
- // avoiding sign makes padding easier
- const val = expandNumber(Math.abs(n)) as string;
- const arr = val.split(".");
- const dig = arr[0];
- let fractional = arr[1];
-
- const precision = this.flags.precision !== -1
- ? this.flags.precision
- : DEFAULT_PRECISION;
- fractional = this.roundFractionToPrecision(fractional, precision);
-
- return this.padNum(`${dig}.${fractional}`, n < 0);
- }
-
- /**
- * Format float G
- * @param n
- * @param upcase
- */
- fmtFloatG(n: number, upcase = false): string {
- const special = this.fmtFloatSpecial(n);
- if (special !== "") {
- return special;
- }
-
- // The double argument representing a floating-point number shall be
- // converted in the style f or e (or in the style F or E in
- // the case of a G conversion specifier), depending on the
- // value converted and the precision. Let P equal the
- // precision if non-zero, 6 if the precision is omitted, or 1
- // if the precision is zero. Then, if a conversion with style E would
- // have an exponent of X:
-
- // - If P > X>=-4, the conversion shall be with style f (or F )
- // and precision P -( X+1).
-
- // - Otherwise, the conversion shall be with style e (or E )
- // and precision P -1.
-
- // Finally, unless the '#' flag is used, any trailing zeros shall be
- // removed from the fractional portion of the result and the
- // decimal-point character shall be removed if there is no
- // fractional portion remaining.
-
- // A double argument representing an infinity or NaN shall be
- // converted in the style of an f or F conversion specifier.
- // https://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html
-
- let P = this.flags.precision !== -1
- ? this.flags.precision
- : DEFAULT_PRECISION;
- P = P === 0 ? 1 : P;
-
- const m = n.toExponential().match(FLOAT_REGEXP);
- if (!m) {
- throw Error("can't happen");
- }
-
- const X = parseInt(m[F.exponent]) * (m[F.esign] === "-" ? -1 : 1);
- let nStr = "";
- if (P > X && X >= -4) {
- this.flags.precision = P - (X + 1);
- nStr = this.fmtFloatF(n);
- if (!this.flags.sharp) {
- nStr = nStr.replace(/\.?0*$/, "");
- }
- } else {
- this.flags.precision = P - 1;
- nStr = this.fmtFloatE(n);
- if (!this.flags.sharp) {
- nStr = nStr.replace(/\.?0*e/, upcase ? "E" : "e");
- }
- }
- return nStr;
- }
-
- /**
- * Format string
- * @param s
- */
- fmtString(s: string): string {
- if (this.flags.precision !== -1) {
- s = s.substr(0, this.flags.precision);
- }
- return this.pad(s);
- }
-
- /**
- * Format hex
- * @param val
- * @param upper
- */
- fmtHex(val: string | number, upper = false): string {
- // allow others types ?
- switch (typeof val) {
- case "number":
- return this.fmtNumber(val as number, 16, upper);
- case "string": {
- const sharp = this.flags.sharp && val.length !== 0;
- let hex = sharp ? "0x" : "";
- const prec = this.flags.precision;
- const end = prec !== -1 ? min(prec, val.length) : val.length;
- for (let i = 0; i !== end; ++i) {
- if (i !== 0 && this.flags.space) {
- hex += sharp ? " 0x" : " ";
- }
- // TODO(bartlomieju): for now only taking into account the
- // lower half of the codePoint, ie. as if a string
- // is a list of 8bit values instead of UCS2 runes
- const c = (val.charCodeAt(i) & 0xff).toString(16);
- hex += c.length === 1 ? `0${c}` : c;
- }
- if (upper) {
- hex = hex.toUpperCase();
- }
- return this.pad(hex);
- }
- default:
- throw new Error(
- "currently only number and string are implemented for hex",
- );
- }
- }
-
- /**
- * Format value
- * @param val
- */
- fmtV(val: Record<string, unknown>): string {
- if (this.flags.sharp) {
- const options = this.flags.precision !== -1
- ? { depth: this.flags.precision }
- : {};
- return this.pad(Deno.inspect(val, options));
- } else {
- const p = this.flags.precision;
- return p === -1 ? val.toString() : val.toString().substr(0, p);
- }
- }
-
- /**
- * Format JSON
- * @param val
- */
- fmtJ(val: unknown): string {
- return JSON.stringify(val);
- }
-}
-
-/**
- * Converts and format a variable number of `args` as is specified by `format`.
- * `sprintf` returns the formatted string.
- *
- * @param format
- * @param args
- */
-export function sprintf(format: string, ...args: unknown[]): string {
- const printf = new Printf(format, ...args);
- return printf.doPrintf();
-}
-
-/**
- * Converts and format a variable number of `args` as is specified by `format`.
- * `printf` writes the formatted string to standard output.
- * @param format
- * @param args
- */
-export function printf(format: string, ...args: unknown[]): void {
- const s = sprintf(format, ...args);
- Deno.stdout.writeSync(new TextEncoder().encode(s));
-}
diff --git a/std/fmt/printf_test.ts b/std/fmt/printf_test.ts
deleted file mode 100644
index f24085848..000000000
--- a/std/fmt/printf_test.ts
+++ /dev/null
@@ -1,674 +0,0 @@
-// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-//
-// A number of test-cases based on:
-//
-// https://golang.org/src/fmt/fmt_test.go
-// BSD: Copyright (c) 2009 The Go Authors. All rights reserved.
-
-import { sprintf } from "./printf.ts";
-import { assertEquals } from "../testing/asserts.ts";
-
-const S = sprintf;
-
-Deno.test("noVerb", function (): void {
- assertEquals(sprintf("bla"), "bla");
-});
-
-Deno.test("percent", function (): void {
- assertEquals(sprintf("%%"), "%");
- assertEquals(sprintf("!%%!"), "!%!");
- assertEquals(sprintf("!%%"), "!%");
- assertEquals(sprintf("%%!"), "%!");
-});
-Deno.test("testBoolean", function (): void {
- assertEquals(sprintf("%t", true), "true");
- assertEquals(sprintf("%10t", true), " true");
- assertEquals(sprintf("%-10t", false), "false ");
- assertEquals(sprintf("%t", false), "false");
- assertEquals(sprintf("bla%t", true), "blatrue");
- assertEquals(sprintf("%tbla", false), "falsebla");
-});
-
-Deno.test("testIntegerB", function (): void {
- assertEquals(S("%b", 4), "100");
- assertEquals(S("%b", -4), "-100");
- assertEquals(
- S("%b", 4.1),
- "100.0001100110011001100110011001100110011001100110011",
- );
- assertEquals(
- S("%b", -4.1),
- "-100.0001100110011001100110011001100110011001100110011",
- );
- assertEquals(
- S("%b", Number.MAX_SAFE_INTEGER),
- "11111111111111111111111111111111111111111111111111111",
- );
- assertEquals(
- S("%b", Number.MIN_SAFE_INTEGER),
- "-11111111111111111111111111111111111111111111111111111",
- );
- // width
-
- assertEquals(S("%4b", 4), " 100");
-});
-
-Deno.test("testIntegerC", function (): void {
- assertEquals(S("%c", 0x31), "1");
- assertEquals(S("%c%b", 0x31, 1), "11");
- assertEquals(S("%c", 0x1f4a9), "💩");
- //width
- assertEquals(S("%4c", 0x31), " 1");
-});
-
-Deno.test("testIntegerD", function (): void {
- assertEquals(S("%d", 4), "4");
- assertEquals(S("%d", -4), "-4");
- assertEquals(S("%d", Number.MAX_SAFE_INTEGER), "9007199254740991");
- assertEquals(S("%d", Number.MIN_SAFE_INTEGER), "-9007199254740991");
-});
-
-Deno.test("testIntegerO", function (): void {
- assertEquals(S("%o", 4), "4");
- assertEquals(S("%o", -4), "-4");
- assertEquals(S("%o", 9), "11");
- assertEquals(S("%o", -9), "-11");
- assertEquals(S("%o", Number.MAX_SAFE_INTEGER), "377777777777777777");
- assertEquals(S("%o", Number.MIN_SAFE_INTEGER), "-377777777777777777");
- // width
- assertEquals(S("%4o", 4), " 4");
-});
-Deno.test("testIntegerx", function (): void {
- assertEquals(S("%x", 4), "4");
- assertEquals(S("%x", -4), "-4");
- assertEquals(S("%x", 9), "9");
- assertEquals(S("%x", -9), "-9");
- assertEquals(S("%x", Number.MAX_SAFE_INTEGER), "1fffffffffffff");
- assertEquals(S("%x", Number.MIN_SAFE_INTEGER), "-1fffffffffffff");
- // width
- assertEquals(S("%4x", -4), " -4");
- assertEquals(S("%-4x", -4), "-4 ");
- // plus
- assertEquals(S("%+4x", 4), " +4");
- assertEquals(S("%-+4x", 4), "+4 ");
-});
-Deno.test("testIntegerX", function (): void {
- assertEquals(S("%X", 4), "4");
- assertEquals(S("%X", -4), "-4");
- assertEquals(S("%X", 9), "9");
- assertEquals(S("%X", -9), "-9");
- assertEquals(S("%X", Number.MAX_SAFE_INTEGER), "1FFFFFFFFFFFFF");
- assertEquals(S("%X", Number.MIN_SAFE_INTEGER), "-1FFFFFFFFFFFFF");
-});
-
-Deno.test("testFloate", function (): void {
- assertEquals(S("%e", 4), "4.000000e+00");
- assertEquals(S("%e", -4), "-4.000000e+00");
- assertEquals(S("%e", 4.1), "4.100000e+00");
- assertEquals(S("%e", -4.1), "-4.100000e+00");
- assertEquals(S("%e", Number.MAX_SAFE_INTEGER), "9.007199e+15");
- assertEquals(S("%e", Number.MIN_SAFE_INTEGER), "-9.007199e+15");
-});
-Deno.test("testFloatE", function (): void {
- assertEquals(S("%E", 4), "4.000000E+00");
- assertEquals(S("%E", -4), "-4.000000E+00");
- assertEquals(S("%E", 4.1), "4.100000E+00");
- assertEquals(S("%E", -4.1), "-4.100000E+00");
- assertEquals(S("%E", Number.MAX_SAFE_INTEGER), "9.007199E+15");
- assertEquals(S("%E", Number.MIN_SAFE_INTEGER), "-9.007199E+15");
- assertEquals(S("%E", Number.MIN_VALUE), "5.000000E-324");
- assertEquals(S("%E", Number.MAX_VALUE), "1.797693E+308");
-});
-Deno.test("testFloatfF", function (): void {
- assertEquals(S("%f", 4), "4.000000");
- assertEquals(S("%F", 4), "4.000000");
- assertEquals(S("%f", -4), "-4.000000");
- assertEquals(S("%F", -4), "-4.000000");
- assertEquals(S("%f", 4.1), "4.100000");
- assertEquals(S("%F", 4.1), "4.100000");
- assertEquals(S("%f", -4.1), "-4.100000");
- assertEquals(S("%F", -4.1), "-4.100000");
- assertEquals(S("%f", Number.MAX_SAFE_INTEGER), "9007199254740991.000000");
- assertEquals(S("%F", Number.MAX_SAFE_INTEGER), "9007199254740991.000000");
- assertEquals(S("%f", Number.MIN_SAFE_INTEGER), "-9007199254740991.000000");
- assertEquals(S("%F", Number.MIN_SAFE_INTEGER), "-9007199254740991.000000");
- assertEquals(S("%f", Number.MIN_VALUE), "0.000000");
- assertEquals(
- S("%.324f", Number.MIN_VALUE),
- // eslint-disable-next-line max-len
- "0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005",
- );
- assertEquals(S("%F", Number.MIN_VALUE), "0.000000");
- assertEquals(
- S("%f", Number.MAX_VALUE),
- // eslint-disable-next-line max-len
- "179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000",
- );
- assertEquals(
- S("%F", Number.MAX_VALUE),
- // eslint-disable-next-line max-len
- "179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000",
- );
-});
-
-Deno.test("testString", function (): void {
- assertEquals(S("%s World%s", "Hello", "!"), "Hello World!");
-});
-
-Deno.test("testHex", function (): void {
- assertEquals(S("%x", "123"), "313233");
- assertEquals(S("%x", "n"), "6e");
-});
-Deno.test("testHeX", function (): void {
- assertEquals(S("%X", "123"), "313233");
- assertEquals(S("%X", "n"), "6E");
-});
-
-Deno.test("testType", function (): void {
- assertEquals(S("%T", new Date()), "object");
- assertEquals(S("%T", 123), "number");
- assertEquals(S("%T", "123"), "string");
- assertEquals(S("%.3T", "123"), "str");
-});
-
-Deno.test("testPositional", function (): void {
- assertEquals(S("%[1]d%[2]d", 1, 2), "12");
- assertEquals(S("%[2]d%[1]d", 1, 2), "21");
-});
-
-Deno.test("testSharp", function (): void {
- assertEquals(S("%#x", "123"), "0x313233");
- assertEquals(S("%#X", "123"), "0X313233");
- assertEquals(S("%#x", 123), "0x7b");
- assertEquals(S("%#X", 123), "0X7B");
- assertEquals(S("%#o", 123), "0173");
- assertEquals(S("%#b", 4), "0b100");
-});
-
-Deno.test("testWidthAndPrecision", function (): void {
- assertEquals(
- S("%9.99d", 9),
- // eslint-disable-next-line max-len
- "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009",
- );
- assertEquals(S("%1.12d", 9), "000000000009");
- assertEquals(S("%2s", "a"), " a");
- assertEquals(S("%2d", 1), " 1");
- assertEquals(S("%#4x", 1), " 0x1");
-
- assertEquals(
- S("%*.99d", 9, 9),
- // eslint-disable-next-line max-len
- "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009",
- );
- assertEquals(
- S("%9.*d", 99, 9),
- // eslint-disable-next-line max-len
- "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009",
- );
- assertEquals(S("%*s", 2, "a"), " a");
- assertEquals(S("%*d", 2, 1), " 1");
- assertEquals(S("%#*x", 4, 1), " 0x1");
-});
-
-Deno.test("testDash", function (): void {
- assertEquals(S("%-2s", "a"), "a ");
- assertEquals(S("%-2d", 1), "1 ");
-});
-Deno.test("testPlus", function (): void {
- assertEquals(S("%-+3d", 1), "+1 ");
- assertEquals(S("%+3d", 1), " +1");
- assertEquals(S("%+3d", -1), " -1");
-});
-
-Deno.test("testSpace", function (): void {
- assertEquals(S("% -3d", 3), " 3 ");
-});
-
-Deno.test("testZero", function (): void {
- assertEquals(S("%04s", "a"), "000a");
-});
-
-// relevant test cases from fmt_test.go
-// deno-lint-ignore no-explicit-any
-const tests: Array<[string, any, string]> = [
- ["%d", 12345, "12345"],
- ["%v", 12345, "12345"],
- ["%t", true, "true"],
- // basic string
- ["%s", "abc", "abc"],
- // ["%q", "abc", `"abc"`], // TODO: need %q?
- ["%x", "abc", "616263"],
- ["%x", "\xff\xf0\x0f\xff", "fff00fff"],
- ["%X", "\xff\xf0\x0f\xff", "FFF00FFF"],
- ["%x", "", ""],
- ["% x", "", ""],
- ["%#x", "", ""],
- ["%# x", "", ""],
- ["%x", "xyz", "78797a"],
- ["%X", "xyz", "78797A"],
- ["% x", "xyz", "78 79 7a"],
- ["% X", "xyz", "78 79 7A"],
- ["%#x", "xyz", "0x78797a"],
- ["%#X", "xyz", "0X78797A"],
- ["%# x", "xyz", "0x78 0x79 0x7a"],
- ["%# X", "xyz", "0X78 0X79 0X7A"],
- // basic bytes : TODO special handling for Buffer? other std types?
- // escaped strings : TODO decide whether to have %q
-
- // characters
- ["%c", "x".charCodeAt(0), "x"],
- ["%c", 0xe4, "ä"],
- ["%c", 0x672c, "本"],
- ["%c", "æ—¥".charCodeAt(0), "æ—¥"],
- // Specifying precision should have no effect.
- ["%.0c", "⌘".charCodeAt(0), "⌘"],
- ["%3c", "⌘".charCodeAt(0), " ⌘"],
- ["%-3c", "⌘".charCodeAt(0), "⌘ "],
- // Runes that are not printable.
- // {"%c", '\U00000e00', "\u0e00"},
- // TODO(bartlomieju) check if \U escape exists in js
- //["%c", '\U0010ffff'.codePointAt(0), "\U0010ffff"],
-
- // Runes that are not valid.
- ["%c", -1, "�"],
- // TODO(bartomieju): surrogate half, doesn't make sense in itself, how
- // to determine in JS?
- // ["%c", 0xDC80, "�"],
- ["%c", 0x110000, "�"],
- ["%c", 0xfffffffff, "�"],
- // TODO(bartlomieju):
- // escaped characters
- // Runes that are not printable.
- // Runes that are not valid.
-
- // width
- ["%5s", "abc", " abc"],
- ["%2s", "\u263a", " ☺"],
- ["%-5s", "abc", "abc "],
- ["%05s", "abc", "00abc"],
- ["%5s", "abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"],
- ["%.5s", "abcdefghijklmnopqrstuvwxyz", "abcde"],
- ["%.0s", "日本語日本語", ""],
- ["%.5s", "日本語日本語", "日本語日本"],
- ["%.10s", "日本語日本語", "日本語日本語"],
- // ["%08q", "abc", `000"abc"`],
- // TODO(bartlomieju): verb q
- // ["%-8q", "abc", `"abc" `],
- //["%.5q", "abcdefghijklmnopqrstuvwxyz", `"abcde"`],
- ["%.5x", "abcdefghijklmnopqrstuvwxyz", "6162636465"],
- //["%.3q", "日本語日本語", `"日本語"`],
- //["%.1q", "日本語", `"日"`]
- // change of go testcase utf-8([æ—¥]) = 0xe697a5, utf-16= 65e5 and
- // our %x takes lower byte of string "%.1x", "日本語", "e6"],,
- ["%.1x", "日本語", "e5"],
- //["%10.1q", "日本語日本語", ` "日"`],
- // ["%10v", null, " <nil>"],
- // TODO(bartlomieju): null, undefined ...
- // ["%-10v", null, "<nil> "],
-
- // integers
- ["%d", 12345, "12345"],
- ["%d", -12345, "-12345"],
- // ["%d", ^uint8(0), "255"],
- //["%d", ^uint16(0), "65535"],
- //["%d", ^uint32(0), "4294967295"],
- //["%d", ^uint64(0), "18446744073709551615"],
- ["%d", -1 << 7, "-128"],
- ["%d", -1 << 15, "-32768"],
- ["%d", -1 << 31, "-2147483648"],
- //["%d", (-1 << 63), "-9223372036854775808"],
- ["%.d", 0, ""],
- ["%.0d", 0, ""],
- ["%6.0d", 0, " "],
- ["%06.0d", 0, " "], // 0 flag should be ignored
- ["% d", 12345, " 12345"],
- ["%+d", 12345, "+12345"],
- ["%+d", -12345, "-12345"],
- ["%b", 7, "111"],
- ["%b", -6, "-110"],
- // ["%b", ^uint32(0), "11111111111111111111111111111111"],
- // ["%b", ^uint64(0),
- // "1111111111111111111111111111111111111111111111111111111111111111"],
- // ["%b", int64(-1 << 63), zeroFill("-1", 63, "")],
- // 0 octal notation not allowed in struct node...
- ["%o", parseInt("01234", 8), "1234"],
- ["%#o", parseInt("01234", 8), "01234"],
- // ["%o", ^uint32(0), "37777777777"],
- // ["%o", ^uint64(0), "1777777777777777777777"],
- ["%#X", 0, "0X0"],
- ["%x", 0x12abcdef, "12abcdef"],
- ["%X", 0x12abcdef, "12ABCDEF"],
- // ["%x", ^uint32(0), "ffffffff"],
- // ["%X", ^uint64(0), "FFFFFFFFFFFFFFFF"],
- ["%.20b", 7, "00000000000000000111"],
- ["%10d", 12345, " 12345"],
- ["%10d", -12345, " -12345"],
- ["%+10d", 12345, " +12345"],
- ["%010d", 12345, "0000012345"],
- ["%010d", -12345, "-000012345"],
- ["%20.8d", 1234, " 00001234"],
- ["%20.8d", -1234, " -00001234"],
- ["%020.8d", 1234, " 00001234"],
- ["%020.8d", -1234, " -00001234"],
- ["%-20.8d", 1234, "00001234 "],
- ["%-20.8d", -1234, "-00001234 "],
- ["%-#20.8x", 0x1234abc, "0x01234abc "],
- ["%-#20.8X", 0x1234abc, "0X01234ABC "],
- ["%-#20.8o", parseInt("01234", 8), "00001234 "],
- // Test correct f.intbuf overflow checks.
- // TODO(bartlomieju): lazy
- // unicode format
- // TODO(bartlomieju): decide whether unicode verb makes sense %U
-
- // floats
- ["%+.3e", 0.0, "+0.000e+00"],
- ["%+.3e", 1.0, "+1.000e+00"],
- ["%+.3f", -1.0, "-1.000"],
- ["%+.3F", -1.0, "-1.000"],
- //["%+.3F", float32(-1.0), "-1.000"],
- ["%+07.2f", 1.0, "+001.00"],
- ["%+07.2f", -1.0, "-001.00"],
- ["%-07.2f", 1.0, "1.00 "],
- ["%-07.2f", -1.0, "-1.00 "],
- ["%+-07.2f", 1.0, "+1.00 "],
- ["%+-07.2f", -1.0, "-1.00 "],
- ["%-+07.2f", 1.0, "+1.00 "],
- ["%-+07.2f", -1.0, "-1.00 "],
- ["%+10.2f", +1.0, " +1.00"],
- ["%+10.2f", -1.0, " -1.00"],
- ["% .3E", -1.0, "-1.000E+00"],
- ["% .3e", 1.0, " 1.000e+00"],
- ["%+.3g", 0.0, "+0"],
- ["%+.3g", 1.0, "+1"],
- ["%+.3g", -1.0, "-1"],
- ["% .3g", -1.0, "-1"],
- ["% .3g", 1.0, " 1"],
- // //["%b", float32(1.0), "8388608p-23"],
- // ["%b", 1.0, "4503599627370496p-52"],
- // // Test sharp flag used with floats.
- ["%#g", 1e-323, "1.00000e-323"],
- ["%#g", -1.0, "-1.00000"],
- ["%#g", 1.1, "1.10000"],
- ["%#g", 123456.0, "123456."],
- //["%#g", 1234567.0, "1.234567e+06"],
- // the line above is incorrect in go (according to
- // my posix reading) %f-> prec = prec-1
- ["%#g", 1234567.0, "1.23457e+06"],
- ["%#g", 1230000.0, "1.23000e+06"],
- ["%#g", 1000000.0, "1.00000e+06"],
- ["%#.0f", 1.0, "1."],
- ["%#.0e", 1.0, "1.e+00"],
- ["%#.0g", 1.0, "1."],
- ["%#.0g", 1100000.0, "1.e+06"],
- ["%#.4f", 1.0, "1.0000"],
- ["%#.4e", 1.0, "1.0000e+00"],
- ["%#.4g", 1.0, "1.000"],
- ["%#.4g", 100000.0, "1.000e+05"],
- ["%#.0f", 123.0, "123."],
- ["%#.0e", 123.0, "1.e+02"],
- ["%#.0g", 123.0, "1.e+02"],
- ["%#.4f", 123.0, "123.0000"],
- ["%#.4e", 123.0, "1.2300e+02"],
- ["%#.4g", 123.0, "123.0"],
- ["%#.4g", 123000.0, "1.230e+05"],
- ["%#9.4g", 1.0, " 1.000"],
- // The sharp flag has no effect for binary float format.
- // ["%#b", 1.0, "4503599627370496p-52"], // TODO binary for floats
- // Precision has no effect for binary float format.
- //["%.4b", float32(1.0), "8388608p-23"], // TODO s.above
- // ["%.4b", -1.0, "-4503599627370496p-52"],
- // Test correct f.intbuf boundary checks.
- //["%.68f", 1.0, zeroFill("1.", 68, "")], // TODO zerofill
- //["%.68f", -1.0, zeroFill("-1.", 68, "")], //TODO s.a.
- // float infinites and NaNs
- ["%f", Number.POSITIVE_INFINITY, "+Inf"],
- ["%.1f", Number.NEGATIVE_INFINITY, "-Inf"],
- ["% f", NaN, " NaN"],
- ["%20f", Number.POSITIVE_INFINITY, " +Inf"],
- // ["% 20F", Number.POSITIVE_INFINITY, " Inf"], // TODO : wut?
- ["% 20e", Number.NEGATIVE_INFINITY, " -Inf"],
- ["%+20E", Number.NEGATIVE_INFINITY, " -Inf"],
- ["% +20g", Number.NEGATIVE_INFINITY, " -Inf"],
- ["%+-20G", Number.POSITIVE_INFINITY, "+Inf "],
- ["%20e", NaN, " NaN"],
- ["% +20E", NaN, " +NaN"],
- ["% -20g", NaN, " NaN "],
- ["%+-20G", NaN, "+NaN "],
- // Zero padding does not apply to infinities and NaN.
- ["%+020e", Number.POSITIVE_INFINITY, " +Inf"],
- ["%-020f", Number.NEGATIVE_INFINITY, "-Inf "],
- ["%-020E", NaN, "NaN "],
- // complex values // go specific
- // old test/fmt_test.go
- ["%e", 1.0, "1.000000e+00"],
- ["%e", 1234.5678e3, "1.234568e+06"],
- ["%e", 1234.5678e-8, "1.234568e-05"],
- ["%e", -7.0, "-7.000000e+00"],
- ["%e", -1e-9, "-1.000000e-09"],
- ["%f", 1234.5678e3, "1234567.800000"],
- ["%f", 1234.5678e-8, "0.000012"],
- ["%f", -7.0, "-7.000000"],
- ["%f", -1e-9, "-0.000000"],
- // ["%g", 1234.5678e3, "1.2345678e+06"],
- // I believe the above test from go is incorrect according to posix, s. above.
- ["%g", 1234.5678e3, "1.23457e+06"],
- //["%g", float32(1234.5678e3), "1.2345678e+06"],
- //["%g", 1234.5678e-8, "1.2345678e-05"], // posix, see above
- ["%g", 1234.5678e-8, "1.23457e-05"],
- ["%g", -7.0, "-7"],
- ["%g", -1e-9, "-1e-09"],
- //["%g", float32(-1e-9), "-1e-09"],
- ["%E", 1.0, "1.000000E+00"],
- ["%E", 1234.5678e3, "1.234568E+06"],
- ["%E", 1234.5678e-8, "1.234568E-05"],
- ["%E", -7.0, "-7.000000E+00"],
- ["%E", -1e-9, "-1.000000E-09"],
- //["%G", 1234.5678e3, "1.2345678E+06"], // posix, see above
- ["%G", 1234.5678e3, "1.23457E+06"],
- //["%G", float32(1234.5678e3), "1.2345678E+06"],
- //["%G", 1234.5678e-8, "1.2345678E-05"], // posic, see above
- ["%G", 1234.5678e-8, "1.23457E-05"],
- ["%G", -7.0, "-7"],
- ["%G", -1e-9, "-1E-09"],
- //["%G", float32(-1e-9), "-1E-09"],
- ["%20.5s", "qwertyuiop", " qwert"],
- ["%.5s", "qwertyuiop", "qwert"],
- ["%-20.5s", "qwertyuiop", "qwert "],
- ["%20c", "x".charCodeAt(0), " x"],
- ["%-20c", "x".charCodeAt(0), "x "],
- ["%20.6e", 1.2345e3, " 1.234500e+03"],
- ["%20.6e", 1.2345e-3, " 1.234500e-03"],
- ["%20e", 1.2345e3, " 1.234500e+03"],
- ["%20e", 1.2345e-3, " 1.234500e-03"],
- ["%20.8e", 1.2345e3, " 1.23450000e+03"],
- ["%20f", 1.23456789e3, " 1234.567890"],
- ["%20f", 1.23456789e-3, " 0.001235"],
- ["%20f", 12345678901.23456789, " 12345678901.234568"],
- ["%-20f", 1.23456789e3, "1234.567890 "],
- ["%20.8f", 1.23456789e3, " 1234.56789000"],
- ["%20.8f", 1.23456789e-3, " 0.00123457"],
- // ["%g", 1.23456789e3, "1234.56789"],
- // posix ... precision(2) = precision(def=6) - (exp(3)+1)
- ["%g", 1.23456789e3, "1234.57"],
- // ["%g", 1.23456789e-3, "0.00123456789"], posix...
- ["%g", 1.23456789e-3, "0.00123457"], // see above prec6 = precdef6 - (-3+1)
- //["%g", 1.23456789e20, "1.23456789e+20"],
- ["%g", 1.23456789e20, "1.23457e+20"],
- // arrays
- // TODO(bartlomieju):
- // slice : go specific
-
- // TODO(bartlomieju): decide how to handle deeper types, arrays, objects
- // byte arrays and slices with %b,%c,%d,%o,%U and %v
- // f.space should and f.plus should not have an effect with %v.
- // f.space and f.plus should have an effect with %d.
-
- // Padding with byte slices.
- // Same for strings
- ["%2x", "", " "], // 103
- ["%#2x", "", " "],
- ["% 02x", "", "00"],
- ["%# 02x", "", "00"],
- ["%-2x", "", " "],
- ["%-02x", "", " "],
- ["%8x", "\xab", " ab"],
- ["% 8x", "\xab", " ab"],
- ["%#8x", "\xab", " 0xab"],
- ["%# 8x", "\xab", " 0xab"],
- ["%08x", "\xab", "000000ab"],
- ["% 08x", "\xab", "000000ab"],
- ["%#08x", "\xab", "00000xab"],
- ["%# 08x", "\xab", "00000xab"],
- ["%10x", "\xab\xcd", " abcd"],
- ["% 10x", "\xab\xcd", " ab cd"],
- ["%#10x", "\xab\xcd", " 0xabcd"],
- ["%# 10x", "\xab\xcd", " 0xab 0xcd"],
- ["%010x", "\xab\xcd", "000000abcd"],
- ["% 010x", "\xab\xcd", "00000ab cd"],
- ["%#010x", "\xab\xcd", "00000xabcd"],
- ["%# 010x", "\xab\xcd", "00xab 0xcd"],
- ["%-10X", "\xab", "AB "],
- ["% -010X", "\xab", "AB "],
- ["%#-10X", "\xab\xcd", "0XABCD "],
- ["%# -010X", "\xab\xcd", "0XAB 0XCD "],
- // renamings
- // Formatter
- // GoStringer
-
- // %T TODO possibly %#T object(constructor)
- ["%T", {}, "object"],
- ["%T", 1, "number"],
- ["%T", "", "string"],
- ["%T", undefined, "undefined"],
- ["%T", null, "object"],
- ["%T", S, "function"],
- ["%T", true, "boolean"],
- ["%T", Symbol(), "symbol"],
- // %p with pointers
-
- // erroneous things
- // {"", nil, "%!(EXTRA <nil>)"},
- // {"", 2, "%!(EXTRA int=2)"},
- // {"no args", "hello", "no args%!(EXTRA string=hello)"},
- // {"%s %", "hello", "hello %!(NOVERB)"},
- // {"%s %.2", "hello", "hello %!(NOVERB)"},
- // {"%017091901790959340919092959340919017929593813360", 0,
- // "%!(NOVERB)%!(EXTRA int=0)"},
- // {"%184467440737095516170v", 0, "%!(NOVERB)%!(EXTRA int=0)"},
- // // Extra argument errors should format without flags set.
- // {"%010.2", "12345", "%!(NOVERB)%!(EXTRA string=12345)"},
- //
- // // Test that maps with non-reflexive keys print all keys and values.
- // {"%v", map[float64]int{NaN: 1, NaN: 1}, "map[NaN:1 NaN:1]"},
-
- // more floats
-
- ["%.2f", 1.0, "1.00"],
- ["%.2f", -1.0, "-1.00"],
- ["% .2f", 1.0, " 1.00"],
- ["% .2f", -1.0, "-1.00"],
- ["%+.2f", 1.0, "+1.00"],
- ["%+.2f", -1.0, "-1.00"],
- ["%7.2f", 1.0, " 1.00"],
- ["%7.2f", -1.0, " -1.00"],
- ["% 7.2f", 1.0, " 1.00"],
- ["% 7.2f", -1.0, " -1.00"],
- ["%+7.2f", 1.0, " +1.00"],
- ["%+7.2f", -1.0, " -1.00"],
- ["% +7.2f", 1.0, " +1.00"],
- ["% +7.2f", -1.0, " -1.00"],
- ["%07.2f", 1.0, "0001.00"],
- ["%07.2f", -1.0, "-001.00"],
- ["% 07.2f", 1.0, " 001.00"], //153 here
- ["% 07.2f", -1.0, "-001.00"],
- ["%+07.2f", 1.0, "+001.00"],
- ["%+07.2f", -1.0, "-001.00"],
- ["% +07.2f", 1.0, "+001.00"],
- ["% +07.2f", -1.0, "-001.00"],
-];
-
-Deno.test("testThorough", function (): void {
- tests.forEach((t, i): void => {
- // p(t)
- const is = S(t[0], t[1]);
- const should = t[2];
- assertEquals(
- is,
- should,
- `failed case[${i}] : is >${is}< should >${should}<`,
- );
- });
-});
-
-Deno.test("testWeirdos", function (): void {
- assertEquals(S("%.d", 9), "9");
- assertEquals(
- S("dec[%d]=%d hex[%[1]d]=%#x oct[%[1]d]=%#o %s", 1, 255, "Third"),
- "dec[1]=255 hex[1]=0xff oct[1]=0377 Third",
- );
-});
-
-Deno.test("formatV", function (): void {
- const a = { a: { a: { a: { a: { a: { a: { a: {} } } } } } } };
- assertEquals(S("%v", a), "[object Object]");
- assertEquals(S("%#v", a), `{ a: { a: { a: { a: [Object] } } } }`);
- assertEquals(
- S("%#.8v", a),
- "{ a: { a: { a: { a: { a: { a: { a: {} } } } } } } }",
- );
- assertEquals(S("%#.1v", a), `{ a: [Object] }`);
-});
-
-Deno.test("formatJ", function (): void {
- const a = { a: { a: { a: { a: { a: { a: { a: {} } } } } } } };
- assertEquals(S("%j", a), `{"a":{"a":{"a":{"a":{"a":{"a":{"a":{}}}}}}}}`);
-});
-
-Deno.test("flagLessThan", function (): void {
- const a = { a: { a: { a: { a: { a: { a: { a: {} } } } } } } };
- const aArray = [a, a, a];
- assertEquals(
- S("%<#.1v", aArray),
- `[ { a: [Object] }, { a: [Object] }, { a: [Object] } ]`,
- );
- const fArray = [1.2345, 0.98765, 123456789.5678];
- assertEquals(S("%<.2f", fArray), "[ 1.23, 0.99, 123456789.57 ]");
-});
-
-Deno.test("testErrors", function (): void {
- // wrong type : TODO strict mode ...
- //assertEquals(S("%f", "not a number"), "%!(BADTYPE flag=f type=string)")
- assertEquals(S("A %h", ""), "A %!(BAD VERB 'h')");
- assertEquals(S("%J", ""), "%!(BAD VERB 'J')");
- assertEquals(S("bla%J", ""), "bla%!(BAD VERB 'J')");
- assertEquals(S("%Jbla", ""), "%!(BAD VERB 'J')bla");
-
- assertEquals(S("%d"), "%!(MISSING 'd')");
- assertEquals(S("%d %d", 1), "1 %!(MISSING 'd')");
- assertEquals(S("%d %f A", 1), "1 %!(MISSING 'f') A");
-
- assertEquals(S("%*.2f", "a", 1.1), "%!(BAD WIDTH 'a')");
- assertEquals(S("%.*f", "a", 1.1), "%!(BAD PREC 'a')");
- assertEquals(
- S("%.[2]*f", 1.23, "p"),
- `%!(BAD PREC 'p')%!(EXTRA '1.23')`,
- );
- assertEquals(S("%.[2]*[1]f Yippie!", 1.23, "p"), "%!(BAD PREC 'p') Yippie!");
-
- assertEquals(S("%[1]*.2f", "a", "p"), "%!(BAD WIDTH 'a')");
-
- assertEquals(S("A", "a", "p"), `A%!(EXTRA '"a"' '"p"')`);
- assertEquals(S("%[2]s %[2]s", "a", "p"), `p p%!(EXTRA '"a"')`);
-
- // remains to be determined how to handle bad indices ...
- // (realistically) the entire error handling is still up for grabs.
- assertEquals(S("%[hallo]s %d %d %d", 1, 2, 3, 4), "%!(BAD INDEX) 2 3 4");
- assertEquals(
- S("%[5]s", 1, 2, 3, 4),
- `%!(BAD INDEX)%!(EXTRA '2' '3' '4')`,
- );
- assertEquals(S("%[5]f"), "%!(BAD INDEX)");
- assertEquals(S("%.[5]f"), "%!(BAD INDEX)");
- assertEquals(S("%.[5]*f"), "%!(BAD INDEX)");
-});