CodeSampleX

Exemple

@jest/console 29.7.0: redirect and format log streams using CustomConsole and NullConsole

Échantillon vérifié pour npm @jest/console 29.7.0: redirect and format log streams using CustomConsole and NullConsole. Le contrat s'est exécuté sur node 22…

sha256:57ac63876189c56e86f10a844b9ddd2578febf6d0bfff4c49a33c26daff6eec6

Ce réseau offre une seule chose : un échantillon qui compile. Il l'a exécuté dans un bac à sable et conservé le reçu signé. Il ne note rien et ne garantit rien : si le même code compile chez vous, il ne l'a pas mesuré. Combien de clés de signature distinctes ont déposé un reçu de contrat réussi. Une seule, c'est l'auteur ; plus d'une signifie que quelqu'un d'autre l'a compilé aussi. Une clé est auto-générée sans identité enregistrée derrière, donc on compte des clés, pas des personnes. MIT-0

Preuves d'exécution

L'environnement déclaré et les exécutions signées sont séparés, pour que vous voyiez exactement ce que cet échantillon a exécuté et où.

Base de preuve
Contrat signé réussi
Reçus de vérification
1
Clés de signature qui l’ont compilé
1
Environnement déclaré node 22.23 linux 24 · ubuntu · glibc 2.39 x64 node 22.23 javascript npm 10

Environnements des exécutions de vérification

Environnement Contrat Étapes Exécution
node 22 · linux alpine/x64 · docker ed25519:c1973797be207ac4 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1node:22-alpine@sha256:c610fcdfb1d5…
2026-08-27

Cas

HOW
Objectif
redirect and format log streams using CustomConsole and NullConsole
Paquets
Symboles
  • CustomConsole
  • NullConsole
Environnement
node 22.23.2
Créé
2026-08-27T17:57:13Z

Contrat

  1. CustomConsole routes stdout methods (log, info, debug, dir, dirxml) to custom stdout stream and stderr methods (warn, error) to custom stderr stream
  2. CustomConsole applies custom formatBuffer transformations to all emitted stdout and stderr messages
  3. CustomConsole indents grouped logs according to groupDepth and bolds group and groupCollapsed titles
  4. CustomConsole tracks named timers with time, timeLog, and timeEnd, and named counters with count and countReset
  5. CustomConsole.assert intercepts AssertionError on falsy conditions and logs to stderr without throwing while passing truthy conditions silently
  6. CustomConsole.getBuffer always returns undefined
  7. NullConsole requires writable streams in constructor and throws ERR_CONSOLE_WRITABLE_STREAM if instantiated without arguments
  8. NullConsole silences all console methods including log, info, warn, error, debug, assert, and timers without emitting output to streams

Fichiers

  • PROMPT.md
  • csx.json
  • index.js
  • package-lock.json
  • package.json
  • spec.json
  • test/contract.js

Télécharger l’artefact source (tar.gz)

Code source

PROMPT.md
Clean-room public code sample — generation instructions

Write a brand-new, minimal, self-contained code sample in this clean-room directory.
Do not copy, paraphrase, or reference any existing project source. Work only from this spec.

A csx.json manifest scaffold already exists. Do not recreate it from memory. Preserve its case.goal, packages and symbols; fill its empty case.contract with exact assertions and correct its environment, commands and verifierAdapter for the files you generate.

Goal: redirect and format log streams using CustomConsole and NullConsole
Kind: HOW

Use EXACTLY these public packages and versions:
  - pkg:npm/%40jest/console@29.7.0
Demonstrate these symbols/APIs:
  - CustomConsole
  - NullConsole

Rules:
  - One focused purpose; the smallest project that proves the goal.
  - Include a contract test (test/contract.*) that runs OFFLINE and exits 0 exactly when the goal behavior works.
  - Pin every dependency with a lockfile so resolution is reproducible.
  - No secrets, credentials, or tokens. No real URLs (only example.com or localhost). No absolute paths.
  - No personal names, emails, company names, or project identifiers of any kind.
  - No binaries and no generated output (node_modules, dist, target, venv, .git, .env).
  - Keep it under 200 files and 256KB packed.
csx.json
{"case":{"caseId":"case:sha256:cb00aa8fc25cfb290fc0358d63d12cddb3c026d3dfe0855220fb7781af54f664","constraints":{"executionContext":"node"},"contract":["CustomConsole routes stdout methods (log, info, debug, dir, dirxml) to custom stdout stream and stderr methods (warn, error) to custom stderr stream","CustomConsole applies custom formatBuffer transformations to all emitted stdout and stderr messages","CustomConsole indents grouped logs according to groupDepth and bolds group and groupCollapsed titles","CustomConsole tracks named timers with time, timeLog, and timeEnd, and named counters with count and countReset","CustomConsole.assert intercepts AssertionError on falsy conditions and logs to stderr without throwing while passing truthy conditions silently","CustomConsole.getBuffer always returns undefined","NullConsole requires writable streams in constructor and throws ERR_CONSOLE_WRITABLE_STREAM if instantiated without arguments","NullConsole silences all console methods including log, info, warn, error, debug, assert, and timers without emitting output to streams"],"goal":"redirect and format log streams using CustomConsole and NullConsole","kind":"HOW","packages":["pkg:npm/%40jest/console@29.7.0"],"schemaVersion":1,"symbols":["CustomConsole","NullConsole"]},"contractCommand":["node","test/contract.js"],"environment":{"arch":"x64","distro":"ubuntu","ecosystem":"npm","executionContext":"node","language":"javascript","libc":"glibc","libcVersion":"2.39","moduleSystem":"cjs","os":"linux","osVersionBucket":"24","packageManager":"npm","packageManagerVersion":"10.9.8","runtime":"node","runtimeVersion":"22.23.2","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/%40jest/console@29.7.0"],"schemaVersion":1,"subject":"pkg:npm/%40jest/console@29.7.0","symbols":["CustomConsole","NullConsole"],"verifierAdapter":"node-typescript@1"}
index.js
'use strict';

const { Writable } = require('stream');
const { CustomConsole, NullConsole } = require('@jest/console');

/**
 * Creates an in-memory writable stream that collects written chunks.
 * @returns {{ stream: Writable, getOutput: () => string, getChunks: () => string[], clear: () => void }}
 */
function createMemoryStream() {
  const chunks = [];
  const stream = new Writable({
    write(chunk, encoding, callback) {
      chunks.push(chunk.toString());
      callback();
    }
  });

  return {
    stream,
    getOutput: () => chunks.join(''),
    getChunks: () => [...chunks],
    clear: () => {
      chunks.length = 0;
    }
  };
}

/**
 * Creates a CustomConsole instance with custom or default memory streams.
 * @param {object} [options]
 * @param {NodeJS.WritableStream} [options.stdout] - Destination stream for standard messages.
 * @param {NodeJS.WritableStream} [options.stderr] - Destination stream for error messages.
 * @param {Function} [options.formatBuffer] - Formatter function: (type, message) => string.
 * @returns {CustomConsole}
 */
function createCustomConsole(options = {}) {
  const stdout = options.stdout || createMemoryStream().stream;
  const stderr = options.stderr || createMemoryStream().stream;
  const formatBuffer = options.formatBuffer || ((_type, message) => message);
  return new CustomConsole(stdout, stderr, formatBuffer);
}

/**
 * Creates a NullConsole instance with default or custom streams.
 * Note: NullConsole requires Writable streams in constructor (inherited from Console).
 * @param {NodeJS.WritableStream} [stdout] - Optional stdout stream.
 * @param {NodeJS.WritableStream} [stderr] - Optional stderr stream.
 * @returns {NullConsole}
 */
function createNullConsole(stdout, stderr) {
  const devNull = () =>
    new Writable({
      write(_chunk, _encoding, callback) {
        callback();
      }
    });
  return new NullConsole(stdout || devNull(), stderr || devNull());
}

/**
 * Executes a callback with console redirected through CustomConsole and returns captured stdout/stderr.
 * @param {Function} fn - Function to execute: (customConsole) => any
 * @param {Function} [formatBuffer] - Optional message formatter.
 * @returns {{ result: any, stdout: string, stderr: string }}
 */
function captureCustomStreamOutput(fn, formatBuffer) {
  const stdoutMem = createMemoryStream();
  const stderrMem = createMemoryStream();
  const customConsole = new CustomConsole(stdoutMem.stream, stderrMem.stream, formatBuffer);

  const originalConsole = global.console;
  let result;
  try {
    global.console = customConsole;
    result = fn(customConsole);
  } finally {
    global.console = originalConsole;
  }

  return {
    result,
    stdout: stdoutMem.getOutput(),
    stderr: stderrMem.getOutput()
  };
}

module.exports = {
  CustomConsole,
  NullConsole,
  createMemoryStream,
  createCustomConsole,
  createNullConsole,
  captureCustomStreamOutput
};
package-lock.json
{
  "name": "sample-jest-console-custom",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "sample-jest-console-custom",
      "version": "1.0.0",
      "license": "MIT-0",
      "dependencies": {
        "@jest/console": "29.7.0"
      }
    },
    "node_modules/@babel/code-frame": {
      "version": "7.29.7",
      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",
      "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",
      "license": "MIT",
      "dependencies": {
        "@babel/helper-validator-identifier": "^7.29.7",
        "js-tokens": "^4.0.0",
        "picocolors": "^1.1.1"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-validator-identifier": {
      "version": "7.29.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
      "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
      "license": "MIT",
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@jest/console": {
      "version": "29.7.0",
      "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz",
      "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==",
      "license": "MIT",
      "dependencies": {
        "@jest/types": "^29.6.3",
        "@types/node": "*",
        "chalk": "^4.0.0",
        "jest-message-util": "^29.7.0",
        "jest-util": "^29.7.0",
        "slash": "^3.0.0"
      },
      "engines": {
        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
      }
    },
    "node_modules/@jest/schemas": {
      "version": "29.6.3",
      "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
      "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
      "license": "MIT",
      "dependencies": {
        "@sinclair/typebox": "^0.27.8"
      },
      "engines": {
        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
      }
    },
    "node_modules/@jest/types": {
      "version": "29.6.3",
      "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
      "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
      "license": "MIT",
      "dependencies": {
        "@jest/schemas": "^29.6.3",
        "@types/istanbul-lib-coverage": "^2.0.0",
        "@types/istanbul-reports": "^3.0.0",
        "@types/node": "*",
        "@types/yargs": "^17.0.8",
        "chalk": "^4.0.0"
      },
      "engines": {
        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
      }
    },
    "node_modules/@sinclair/typebox": {
      "version": "0.27.12",
      "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz",
      "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==",
      "license": "MIT"
    },
    "node_modules/@types/istanbul-lib-coverage": {
      "version": "2.0.6",
      "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
      "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
      "license": "MIT"
    },
    "node_modules/@types/istanbul-lib-report": {
      "version": "3.0.3",
      "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
      "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
      "license": "MIT",
      "dependencies": {
        "@types/istanbul-lib-coverage": "*"
      }
    },
    "node_modules/@types/istanbul-reports": {
      "version": "3.0.4",
      "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
      "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
      "license": "MIT",
      "dependencies": {
        "@types/istanbul-lib-report": "*"
      }
    },
    "node_modules/@types/node": {
      "version": "26.4.0",
      "resolved": "https://registry.npmjs.org/@types/node/-/node-26.4.0.tgz",
      "integrity": "sha512-faiGnoIrLH/V8cibOMEAZ8pMw6oXqSukl29ra4mN8GdaB2ZewzeaLj+INpV5N+Z1eKWzY+IzaIZH2EIR6YZRNQ==",
      "license": "MIT",
      "dependencies": {
        "undici-types": "~8.3.0"
      }
    },
    "node_modules/@types/stack-utils": {
      "version": "2.0.3",
      "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
      "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
      "license": "MIT"
    },
    "node_modules/@types/yargs": {
      "version": "17.0.35",
      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz",
      "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==",
      "license": "MIT",
      "dependencies": {
        "@types/yargs-parser": "*"
      }
    },
    "node_modules/@types/yargs-parser": {
      "version": "21.0.3",
      "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
      "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
      "license": "MIT"
    },
    "node_modules/ansi-styles": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
      "license": "MIT",
      "dependencies": {
        "color-convert": "^2.0.1"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
      }
    },
    "node_modules/braces": {
      "version": "3.0.3",
      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
      "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
      "license": "MIT",
      "dependencies": {
        "fill-range": "^7.1.1"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/chalk": {
      "version": "4.1.2",
      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
      "license": "MIT",
      "dependencies": {
        "ansi-styles": "^4.1.0",
        "supports-color": "^7.1.0"
      },
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/chalk/chalk?sponsor=1"
      }
    },
    "node_modules/ci-info": {
      "version": "3.9.0",
      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
      "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/sibiraj-s"
        }
      ],
      "license": "MIT",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/color-convert": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
      "license": "MIT",
      "dependencies": {
        "color-name": "~1.1.4"
      },
      "engines": {
        "node": ">=7.0.0"
      }
    },
    "node_modules/color-name": {
      "version": "1.1.4",
      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
      "license": "MIT"
    },
    "node_modules/escape-string-regexp": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
      "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
      "license": "MIT",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/fill-range": {
      "version": "7.1.1",
      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
      "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
      "license": "MIT",
      "dependencies": {
        "to-regex-range": "^5.0.1"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/graceful-fs": {
      "version": "4.2.11",
      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
      "license": "ISC"
    },
    "node_modules/has-flag": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
      "license": "MIT",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/is-number": {
      "version": "7.0.0",
      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
      "license": "MIT",
      "engines": {
        "node": ">=0.12.0"
      }
    },
    "node_modules/jest-message-util": {
      "version": "29.7.0",
      "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz",
      "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==",
      "license": "MIT",
      "dependencies": {
        "@babel/code-frame": "^7.12.13",
        "@jest/types": "^29.6.3",
        "@types/stack-utils": "^2.0.0",
        "chalk": "^4.0.0",
        "graceful-fs": "^4.2.9",
        "micromatch": "^4.0.4",
        "pretty-format": "^29.7.0",
        "slash": "^3.0.0",
        "stack-utils": "^2.0.3"
      },
      "engines": {
        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
      }
    },
    "node_modules/jest-util": {
      "version": "29.7.0",
      "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz",
      "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==",
      "license": "MIT",
      "dependencies": {
        "@jest/types": "^29.6.3",
        "@types/node": "*",
        "chalk": "^4.0.0",
        "ci-info": "^3.2.0",
        "graceful-fs": "^4.2.9",
        "picomatch": "^2.2.3"
      },
      "engines": {
        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
      }
    },
    "node_modules/js-tokens": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
      "license": "MIT"
    },
    "node_modules/micromatch": {
      "version": "4.0.8",
      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
      "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
      "license": "MIT",
      "dependencies": {
        "braces": "^3.0.3",
        "picomatch": "^2.3.1"
      },
      "engines": {
        "node": ">=8.6"
      }
    },
    "node_modules/picocolors": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
      "license": "ISC"
    },
    "node_modules/picomatch": {
      "version": "2.3.2",
      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
      "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
      "license": "MIT",
      "engines": {
        "node": ">=8.6"
      },
      "funding": {
        "url": "https://github.com/sponsors/jonschlinkert"
      }
    },
    "node_modules/pretty-format": {
      "version": "29.7.0",
      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
      "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
      "license": "MIT",
      "dependencies": {
        "@jest/schemas": "^29.6.3",
        "ansi-styles": "^5.0.0",
        "react-is": "^18.0.0"
      },
      "engines": {
        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
      }
    },
    "node_modules/pretty-format/node_modules/ansi-styles": {
      "version": "5.2.0",
      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
      "license": "MIT",
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
      }
    },
    "node_modules/react-is": {
      "version": "18.3.1",
      "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
      "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
      "license": "MIT"
    },
    "node_modules/slash": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
      "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
      "license": "MIT",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/stack-utils": {
      "version": "2.0.6",
      "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
      "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
      "license": "MIT",
      "dependencies": {
        "escape-string-regexp": "^2.0.0"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/supports-color": {
      "version": "7.2.0",
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
      "license": "MIT",
      "dependencies": {
        "has-flag": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/to-regex-range": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
      "license": "MIT",
      "dependencies": {
        "is-number": "^7.0.0"
      },
      "engines": {
        "node": ">=8.0"
      }
    },
    "node_modules/undici-types": {
      "version": "8.3.0",
      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz",
      "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==",
      "license": "MIT"
    }
  }
}
package.json
{
  "name": "sample-jest-console-custom",
  "version": "1.0.0",
  "private": true,
  "description": "redirect and format log streams using CustomConsole and NullConsole",
  "main": "index.js",
  "scripts": {
    "test": "node test/contract.js"
  },
  "dependencies": {
    "@jest/console": "29.7.0"
  },
  "license": "MIT-0"
}
spec.json
{
  "schemaVersion": 1,
  "goal": "redirect and format log streams using CustomConsole and NullConsole",
  "kind": "HOW",
  "packages": [
    "pkg:npm/%40jest/console@29.7.0"
  ],
  "symbols": [
    "CustomConsole",
    "NullConsole"
  ]
}
test/contract.js
'use strict';

const assert = require('assert');
const { Writable } = require('stream');
const {
  CustomConsole,
  NullConsole,
  createMemoryStream,
  createCustomConsole,
  createNullConsole,
  captureCustomStreamOutput
} = require('../index.js');

function testStreamRouting() {
  const stdoutMem = createMemoryStream();
  const stderrMem = createMemoryStream();
  const customConsole = createCustomConsole({
    stdout: stdoutMem.stream,
    stderr: stderrMem.stream
  });

  // stdout methods
  customConsole.log('standard log message');
  customConsole.info('informational notice');
  customConsole.debug('debug trace');
  customConsole.dir({ key: 'val' });
  customConsole.dirxml({ tag: 'element' });

  // stderr methods
  customConsole.warn('warning notice');
  customConsole.error('error event');

  const stdoutOutput = stdoutMem.getOutput();
  const stderrOutput = stderrMem.getOutput();

  assert.match(stdoutOutput, /standard log message\n/);
  assert.match(stdoutOutput, /informational notice\n/);
  assert.match(stdoutOutput, /debug trace\n/);
  assert.match(stdoutOutput, /key: 'val'/);
  assert.match(stdoutOutput, /tag: 'element'/);
  assert.doesNotMatch(stdoutOutput, /warning notice/);
  assert.doesNotMatch(stdoutOutput, /error event/);

  assert.match(stderrOutput, /warning notice\n/);
  assert.match(stderrOutput, /error event\n/);
  assert.doesNotMatch(stderrOutput, /standard log message/);
  assert.doesNotMatch(stderrOutput, /informational notice/);
}

function testFormatBuffer() {
  const stdoutMem = createMemoryStream();
  const stderrMem = createMemoryStream();
  const formatBuffer = (type, message) => `[${type.toUpperCase()}] ${message}`;

  const customConsole = createCustomConsole({
    stdout: stdoutMem.stream,
    stderr: stderrMem.stream,
    formatBuffer
  });

  customConsole.log('custom formatted message');
  customConsole.warn('custom formatted warning');
  customConsole.error('custom formatted error');

  const stdoutOutput = stdoutMem.getOutput();
  const stderrOutput = stderrMem.getOutput();

  assert.match(stdoutOutput, /\[LOG\] custom formatted message\n/);
  assert.match(stderrOutput, /\[WARN\] custom formatted warning\n/);
  assert.match(stderrOutput, /\[ERROR\] custom formatted error\n/);
}

function testGrouping() {
  const stdoutMem = createMemoryStream();
  const stderrMem = createMemoryStream();
  const customConsole = createCustomConsole({
    stdout: stdoutMem.stream,
    stderr: stderrMem.stream
  });

  customConsole.group('Parent Group');
  customConsole.log('nested item 1');
  customConsole.groupCollapsed('Child Group');
  customConsole.log('deeply nested item');
  customConsole.groupEnd();
  customConsole.log('nested item 2');
  customConsole.groupEnd();
  customConsole.log('root item');

  const stdoutOutput = stdoutMem.getOutput();
  assert.match(stdoutOutput, /Parent Group/);
  assert.match(stdoutOutput, /  nested item 1\n/);
  assert.match(stdoutOutput, /Child Group/);
  assert.match(stdoutOutput, /    deeply nested item\n/);
  assert.match(stdoutOutput, /  nested item 2\n/);
  assert.match(stdoutOutput, /^root item\n/m);
}

function testTimersAndCounters() {
  const stdoutMem = createMemoryStream();
  const stderrMem = createMemoryStream();
  const customConsole = createCustomConsole({
    stdout: stdoutMem.stream,
    stderr: stderrMem.stream
  });

  customConsole.count('testCounter');
  customConsole.count('testCounter');
  customConsole.countReset('testCounter');
  customConsole.count('testCounter');

  customConsole.time('opTimer');
  customConsole.timeLog('opTimer', 'step1');
  customConsole.timeEnd('opTimer');

  const stdoutOutput = stdoutMem.getOutput();
  assert.match(stdoutOutput, /testCounter: 1/);
  assert.match(stdoutOutput, /testCounter: 2/);
  assert.match(stdoutOutput, /opTimer: \d+(\.\d+)?\s*(ms|s)/);
}

function testAssertions() {
  const stdoutMem = createMemoryStream();
  const stderrMem = createMemoryStream();
  const customConsole = createCustomConsole({
    stdout: stdoutMem.stream,
    stderr: stderrMem.stream
  });

  // Truthy condition must not log anything
  customConsole.assert(true, 'truthy condition must not log');
  assert.strictEqual(stderrMem.getOutput(), '');

  // Falsy condition must log formatted assertion error to stderr without throwing
  customConsole.assert(false, 'falsy condition logged');
  const stderrOutput = stderrMem.getOutput();
  assert.match(stderrOutput, /AssertionError/);
  assert.match(stderrOutput, /falsy condition logged/);
}

function testGetBuffer() {
  const stdoutMem = createMemoryStream();
  const stderrMem = createMemoryStream();
  const customConsole = createCustomConsole({
    stdout: stdoutMem.stream,
    stderr: stderrMem.stream
  });

  customConsole.log('some log entry');
  customConsole.error('some error entry');

  assert.strictEqual(customConsole.getBuffer(), undefined);
}

function testNullConsoleConstructor() {
  // NullConsole requires streams in constructor, otherwise throws ERR_CONSOLE_WRITABLE_STREAM
  assert.throws(
    () => {
      new NullConsole();
    },
    (err) => {
      assert.strictEqual(err.code, 'ERR_CONSOLE_WRITABLE_STREAM');
      return true;
    }
  );

  const nullConsole = createNullConsole();
  assert.ok(nullConsole instanceof NullConsole);
  assert.ok(nullConsole instanceof CustomConsole);
}

function testNullConsoleSilencing() {
  const stdoutMem = createMemoryStream();
  const stderrMem = createMemoryStream();
  const nullConsole = new NullConsole(stdoutMem.stream, stderrMem.stream);

  nullConsole.log('silenced log');
  nullConsole.info('silenced info');
  nullConsole.warn('silenced warn');
  nullConsole.error('silenced error');
  nullConsole.debug('silenced debug');
  nullConsole.assert(false, 'silenced assert');
  nullConsole.dir({ a: 1 });
  nullConsole.time('timer');
  nullConsole.timeLog('timer');
  nullConsole.timeEnd('timer');
  nullConsole.group('group');
  nullConsole.groupCollapsed('collapsed');
  nullConsole.groupEnd();
  nullConsole.trace('trace');

  assert.strictEqual(stdoutMem.getOutput(), '');
  assert.strictEqual(stderrMem.getOutput(), '');
  assert.strictEqual(nullConsole.getBuffer(), undefined);
}

function testCaptureCustomStreamOutput() {
  const result = captureCustomStreamOutput(
    (c) => {
      c.log('captured stdout');
      c.error('captured stderr');
      return 42;
    },
    (type, msg) => `<${type}>${msg}`
  );

  assert.strictEqual(result.result, 42);
  assert.match(result.stdout, /<log>captured stdout\n/);
  assert.match(result.stderr, /<error>captured stderr\n/);
}

function runAll() {
  testStreamRouting();
  testFormatBuffer();
  testGrouping();
  testTimersAndCounters();
  testAssertions();
  testGetBuffer();
  testNullConsoleConstructor();
  testNullConsoleSilencing();
  testCaptureCustomStreamOutput();

  console.log('Contract tests passed successfully.');
  process.exit(0);
}

runAll();

Seeder d'origine

anonyme