mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 18:38:55 +00:00
235 lines
10 KiB
TypeScript
235 lines
10 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
||
import { spawnSync } from "bun";
|
||
import { bunExe, bunEnv } from "harness";
|
||
|
||
describe("console.table", () => {
|
||
test("throws when second arg is invalid", () => {
|
||
expect(() => console.table({})).not.toThrow();
|
||
expect(() => console.table({}, [])).not.toThrow();
|
||
// @ts-expect-error
|
||
expect(() => console.table({}, "invalid")).toThrow();
|
||
});
|
||
|
||
test.each([
|
||
[
|
||
"not object (number)",
|
||
{
|
||
args: () => [42],
|
||
},
|
||
],
|
||
[
|
||
"not object (string)",
|
||
{
|
||
args: () => ["bun"],
|
||
},
|
||
],
|
||
[
|
||
"object - empty",
|
||
{
|
||
args: () => [{}],
|
||
},
|
||
],
|
||
[
|
||
"object",
|
||
{
|
||
args: () => [{ a: 42, b: "bun" }],
|
||
},
|
||
],
|
||
[
|
||
"array - empty",
|
||
{
|
||
args: () => [[]],
|
||
},
|
||
],
|
||
[
|
||
"array - plain",
|
||
{
|
||
args: () => [[42, "bun"]],
|
||
},
|
||
],
|
||
[
|
||
"array - object",
|
||
{
|
||
args: () => [[{ a: 42, b: "bun" }]],
|
||
},
|
||
],
|
||
[
|
||
"array - objects with diff props",
|
||
{
|
||
args: () => [[{ b: "bun" }, { a: 42 }]],
|
||
},
|
||
],
|
||
[
|
||
"array - mixed",
|
||
{
|
||
args: () => [[{ a: 42, b: "bun" }, 42]],
|
||
},
|
||
],
|
||
[
|
||
"set",
|
||
{
|
||
args: () => [new Set([42, "bun"])],
|
||
},
|
||
],
|
||
[
|
||
"map",
|
||
{
|
||
args: () => [
|
||
new Map<any, any>([
|
||
["a", 42],
|
||
["b", "bun"],
|
||
[42, "c"],
|
||
]),
|
||
],
|
||
},
|
||
],
|
||
[
|
||
"properties",
|
||
{
|
||
args: () => [[{ a: 42, b: "bun" }], ["b", "c", "a"]],
|
||
},
|
||
],
|
||
[
|
||
"properties - empty",
|
||
{
|
||
args: () => [[{ a: 42, b: "bun" }], []],
|
||
},
|
||
],
|
||
[
|
||
"properties - interesting character",
|
||
{
|
||
args: () => [
|
||
{
|
||
a: "_字",
|
||
},
|
||
],
|
||
},
|
||
],
|
||
[
|
||
"values - array",
|
||
{
|
||
args: () => [
|
||
[
|
||
{ value: { a: 42, b: "bun" } },
|
||
{ value: [42, "bun"] },
|
||
{ value: new Set([42, "bun"]) },
|
||
{
|
||
value: new Map<any, any>([
|
||
[42, "bun"],
|
||
["bun", 42],
|
||
]),
|
||
},
|
||
],
|
||
],
|
||
},
|
||
],
|
||
[
|
||
"headers object",
|
||
{
|
||
args: () => [
|
||
new Headers([
|
||
["abc", "bun"],
|
||
["potato", "tomato"],
|
||
]),
|
||
],
|
||
},
|
||
],
|
||
])("expected output for: %s", (label, { args }) => {
|
||
const { stdout } = spawnSync({
|
||
cmd: [bunExe(), `${import.meta.dir}/console-table-run.ts`, args.toString()],
|
||
stdout: "pipe",
|
||
stderr: "inherit",
|
||
env: bunEnv,
|
||
});
|
||
|
||
const actualOutput = stdout.toString();
|
||
expect(actualOutput).toMatchSnapshot();
|
||
console.log(actualOutput);
|
||
});
|
||
});
|
||
|
||
test("console.table json fixture", () => {
|
||
const { stdout } = spawnSync({
|
||
cmd: [
|
||
bunExe(),
|
||
`${import.meta.dir}/console-table-run.ts`,
|
||
`(() => [${JSON.stringify(require("./console-table-json-fixture.json"), null, 2)}])`,
|
||
],
|
||
stdout: "pipe",
|
||
stderr: "inherit",
|
||
env: bunEnv,
|
||
});
|
||
|
||
const actualOutput = stdout
|
||
.toString()
|
||
// todo: fix bug causing this to be necessary:
|
||
.replaceAll("`", "'");
|
||
expect(actualOutput).toMatchSnapshot();
|
||
console.log(actualOutput);
|
||
});
|
||
|
||
test("console.table ansi colors", () => {
|
||
const obj = {
|
||
[ansify("hello")]: ansify("this is a long string with ansi color codes"),
|
||
[ansify("world")]: ansify("this is another long string with ansi color"),
|
||
[ansify("foo")]: ansify("bar"),
|
||
};
|
||
|
||
function ansify(str: string) {
|
||
return `\u001b[31m${str}\u001b[39m`;
|
||
}
|
||
|
||
const { stdout } = spawnSync({
|
||
cmd: [bunExe(), `${import.meta.dir}/console-table-run.ts`, `(() => [${JSON.stringify(obj, null, 2)}])`],
|
||
stdout: "pipe",
|
||
stderr: "inherit",
|
||
env: bunEnv,
|
||
});
|
||
|
||
const actualOutput = stdout
|
||
.toString()
|
||
// todo: fix bug causing this to be necessary:
|
||
.replaceAll("`", "'");
|
||
expect(actualOutput).toMatchSnapshot();
|
||
console.log(actualOutput);
|
||
});
|
||
|
||
test.skip("console.table character widths", () => {
|
||
// note: this test cannot be automated because cannot test printed witdhs consistently.
|
||
// so this test is just meant to be run manually
|
||
|
||
// top ~2000 most used unicode codepoints
|
||
const str = `~!@#$%^&*()_-+={[}]|:;"'<,>.?/¡¢£¤¥¦§¨©ª«¬ ®¯°±²³´µ¶·¸ʻ¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿŁłŃńŅņŇňŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŴŵŶŷŸŹźŻżŽžſƆƎƜɐɑɒɔɘəɛɜɞɟɡɢɣɤɥɨɪɬɮɯɰɴɵɶɷɸɹʁʇʌʍʎʞΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρςστυφχψωАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяᴀᴁᴂᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌᴍᴎᴏᴐᴑᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜᴝᴞᴟᴠᴡᴢᴣᴤᴥᴦᴧᴨᴩᴪẞỲỳỴỵỸỹ‐‑‒–—―‖‗‘’‚‛“”„‟†‡•‣․‥…‧‰‱′″‴‵‶‷‸‹›※‼‽‾‿⁀⁁⁂⁃⁄⁅⁆⁇⁈⁉⁊⁋⁌⁍⁎⁏⁐⁑⁒⁓⁔⁕⁗⁰ⁱ⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾ⁿ₀₁₂₃₄₅₆₇₈₉₊₋₌₍₎₠₡₢₣₤₥₦₧₨₩₪₫€₭₮₯₰₱₲₳₴₵₶₷₸₹℀℁ℂ℃℄℅℆ℇ℈℉ℊℋℌℍℎℏℐℑℒℓ℔ℕ№℗℘ℙℚℛℜℝ℞℟℠℡™℣ℤ℥Ω℧ℨ℩Åℬℭ℮ℯℰℱℲℳℴℵℶℷℸ⅁⅂⅃⅄ⅅⅆⅇⅈⅉ⅋ⅎ⅐⅑⅒⅓⅔⅕⅖⅗⅘⅙⅚⅛⅜⅝⅞⅟ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫⅬⅭⅮⅯⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹⅺⅻⅼⅽⅾⅿↄ←↑→↓↔↕↖↗↘↙↚↛↜↝↞↟↠↡↢↣↤↥↦↧↨↩↪↫↬↭↮↯↰↱↲↳↴↵↶↷↸↹↺↻↼↽↾↿⇀⇁⇂⇃⇄⇅⇆⇇⇈⇉⇊⇋⇌⇍⇎⇏⇐⇑⇒⇓⇔⇕⇖⇗⇘⇙⇚⇛⇜⇝⇞⇟⇠⇡⇢⇣⇤⇥⇦⇧⇨⇩⇪⇫⇬⇭⇮⇯⇰⇱⇲⇳⇴⇵⇶⇷⇸⇹⇺⇻⇼⇽⇾⇿∀∁∂∃∄∅∆∇∈∉∊∋∌∍∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡∢∣∤∥∦∧∨∩∪∫∬∭∮∯∰∱∲∳∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝≞≟≠≡≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⌀⌁⌂⌃⌄⌅⌆⌇⌈⌉⌊⌋⌐⌑⌒⌓⌔⌕⌖⌗⌘⌙⌚⌛⌠⌡⌢⌣⌤⌥⌦⌧⌨⌫⌬⎛⎜⎝⎞⎟⎠⎡⎢⎣⎤⎥⎦⎧⎨⎩⎪⎫⎬⎭⏎⏏⏚⏛⏰⏱⏲⏳␢␣─━│┃┄┅┆┇┈┉┊┋┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋╌╍╎╏═║╒╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡╢╣╤╥╦╧╨╩╪╫╬╭╮╯╰╱╲╳╴╵╶╷╸╹╺╻╼╽╾╿▀▁▂▃▄▅▆▇█▉▊▋▌▍▎▏▐░▒▓▔▕▖▗▘▙▚▛▜▝▞▟■□▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱▲△▴▵▶▷▸▹►▻▼▽▾▿◀◁◂◃◄◅◆◇◈◉◊○◌◍◎●◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳◴◵◶◷◸◹◺◻◼◽◾◿☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓☔☕☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚐⚑⚒⚓⚔⚕⚖⚗⚘⚙⚚⚛⚜⚝⚞⚟⚠⚡⚢⚣⚤⚥⚦⚧⚨⚩⚪⚫⚬⚭⚮⚯⚰⚱⚲⚳⚴⚵⚶⚷⚸⚹⚺⚻⚼⛀⛁⛂⛃⛢⛤⛥⛦⛧⛨⛩⛪⛫⛬⛭⛮⛯⛰⛱⛲⛳⛴⛵⛶⛷⛸⛹⛺⛻⛼⛽⛾⛿✁✂✃✄✅✆✇✈✉✊✋✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣✤✥✦✧✨✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞❟❠❡❢❣❤❥❦❧➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻➼➽➾⟰⟱⟲⟳⟴⟵⟶⟷⟸⟹⟺⟻⟼⟽⟾⟿⤀⤁⤂⤃⤄⤅⤆⤇⤈⤉⤊⤋⤌⤍⤎⤏⤐⤑⤒⤓⤔⤕⤖⤗⤘⤙⤚⤛⤜⤝⤞⤟⤠⤡⤢⤣⤤⤥⤦⤧⤨⤩⤪⤫⤬⤭⤮⤯⤰⤱⤲⤳⤴⤵⤶⤷⤸⤹⤺⤻⤼⤽⤾⤿⥀⥁⥂⥃⥄⥅⥆⥇⥈⥉⥊⥋⥌⥍⥎⥏⥐⥑⬀⬁⬂⬃⬄⬅⬆⬇⬈⬉⬊⬋⬌⬍⬎⬏⬐⬑⬒⬓⬔⬕⬖⬗⬘⬙⬚ⱠⱡⱣⱥⱦⱭⱯⱰ⸢⸣⸤⸥⸮〃〄fffiflffifflſtst﴾﴿﷼︐︑︒︓︔︕︖︗︘︙︰︱︲︳︴︵︶︷︸︹︺︻︼︽︾︿﹀﹁﹂﹃﹄﹅﹆﹉﹊﹋﹌﹍﹎﹏﹐﹑﹒﹔﹕﹖﹗﹘﹙﹚﹛﹜﹝﹞﹟﹠﹡﹢﹣﹤﹥﹦﹨﹩﹪﹫\ufeff!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~⦅⦆¢£¬ ̄¦¥₩<EFBFBD>`;
|
||
const { stdout } = spawnSync({
|
||
cmd: [
|
||
bunExe(),
|
||
`${import.meta.dir}/console-table-run.ts`,
|
||
`(() => [${JSON.stringify([...str.matchAll(/.{16}|.+/g)].map(g => g[0].split("")))}])`,
|
||
],
|
||
stdout: "pipe",
|
||
stderr: "inherit",
|
||
env: bunEnv,
|
||
});
|
||
const actualOutput = stdout.toString();
|
||
|
||
console.log(actualOutput);
|
||
});
|
||
|
||
test("console.table repeat 50", () => {
|
||
const expected = `┌───┬───┐
|
||
│ │ n │
|
||
├───┼───┤
|
||
│ 0 │ 8 │
|
||
└───┴───┘
|
||
`;
|
||
const { stdout, stderr } = spawnSync({
|
||
cmd: [bunExe(), `${import.meta.dir}/console-table-repeat-50.ts`],
|
||
stdout: "pipe",
|
||
stderr: "pipe",
|
||
env: bunEnv,
|
||
});
|
||
|
||
expect(stdout.toString()).toBe(expected.repeat(50));
|
||
expect(stderr.toString()).toBe("");
|
||
});
|