Skip to content

Instantly share code, notes, and snippets.

@tbeseda
Last active December 15, 2023 01:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tbeseda/4ee8ca5d41008937a18cbb3ea01de664 to your computer and use it in GitHub Desktop.
Save tbeseda/4ee8ca5d41008937a18cbb3ea01de664 to your computer and use it in GitHub Desktop.
print 2 big strings side by side in the terminal

UPDATE: this was published as a module on npm

Usage

Like in a test...

import assert from 'node:assert/strict'
import test from 'node:test'
import sideBySide from './side-by-side.js'

test('Make sure one object is the same as another', () => {
  assert.deepStrictEqual(
    object1,
    object2,
    sideBySide(
      ['EXPECTED', JSON.stringify(object2, null, 2)],
      ['ACTUAL', JSON.stringify(object1, null, 2)],
    ),
  )
})

Output

✖ Make sure one object is the same as another (0.606542ms)
  AssertionError [ERR_ASSERTION]: 
    EXPECTED                  │  ACTUAL
  ────────────────────────────┼────────────────────────────
    {                         │  {
      "type": "pair",         │    "type": "pair",
      "value": [              │    "value": [
        {                     │      {
          "type": null,       │        "type": null,
          "value": "foo"      │        "value": "foo"
        },                    │      },
        {                     │      {
          "type": "pair",     │        "type": "pair",
          "value": [          │        "value": [
            {                 │          {
              "type": null,   │            "type": null,
              "value": "bar"  │            "value": "bar"
            },                │          },
            {                 │          {
              "type": null,   │            "type": null,
              "value": "baz"  │            "value": "baz"
            }                 │          }
          ],                  │        ],
          "bar": "baz"        │        "bar": "baz"
        }                     │      }
      ],                      │    ],
      "foo": "bar:baz"        │    "foo": [
    }                         │      {
                              │        "type": null,
                              │        "value": "bar"
                              │      },
                              │      {
                              │        "type": null,
                              │        "value": "baz"
                              │      }
                              │    ]
                              │  }
/**
* @param {[string, string]} col1
* @param {[string, string]} col2
* @returns {string}
*/
function sideBySide ([label1, string1], [label2, string2]) {
const ls1 = string1.split('\n')
const ls2 = string2.split('\n')
const w1 = Math.max(
label1.length,
ls1.reduce((acc, cur) => Math.max(acc, cur.length), 0),
)
const w2 = Math.max(
label2.length,
ls2.reduce((acc, cur) => Math.max(acc, cur.length), 0),
)
const zipped = Array.from(
Array(Math.max(ls1.length, ls2.length)),
(_, i) => [ls1[i], ls2[i]],
)
const PAD = ' '
const LINE = '─'
const BAR = '│'
const CROSS = '┼'
const header1 = [
PAD,
label1,
' '.repeat(w1 - label1.length),
].join('')
return `
${[header1, BAR, label2].join(PAD)}
${[
LINE.repeat(header1.length + PAD.length),
LINE.repeat(w2 + (PAD.length * 2)),
].join(CROSS)}
${zipped.map(([l1 = '', l2 = '']) => [
PAD,
l1,
' '.repeat(w1 - l1.length),
PAD, BAR, PAD,
l2,
].join('')).join('\n')}`
}
@tbeseda
Copy link
Author

tbeseda commented Dec 7, 2023

It would be cool to support n number of columns. I guess realistically 3 would be the max and 2 is by far the most common when this is used as a testing util.

@nicovalencia
Copy link

This is cool 👍

@tbeseda
Copy link
Author

tbeseda commented Dec 15, 2023

Published to npm so I don't need to copy paste the function across repos
https://www.npmjs.com/package/print-adjacent

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment