Skip to content

feat: add breakLength option for single-line output#50

Open
abhu85 wants to merge 2 commits intoinspect-js:mainfrom
abhu85:feat/breaklength-infinity
Open

feat: add breakLength option for single-line output#50
abhu85 wants to merge 2 commits intoinspect-js:mainfrom
abhu85:feat/breaklength-infinity

Conversation

@abhu85
Copy link
Copy Markdown

@abhu85 abhu85 commented Feb 23, 2026

Summary

Fixes #47

Adds support for the breakLength option, matching Node.js util.inspect behavior. When breakLength is set to Infinity, output will always be single-line regardless of the indent option.

This allows users to get compact, single-line output like:

inspect({ a: 1, b: { c: 3, d: 4 } }, { indent: 2, breakLength: Infinity })
// Returns: '{ a: 1, b: { c: 3, d: 4 } }'

Changes

  • index.js: Add breakLength option validation and logic
    • Accepts positive integers or Infinity
    • When Infinity, forces single-line output by setting indent to null
  • readme.markdown: Document the new breakLength option
  • test/indent-option.js: Add comprehensive tests
    • Validation tests for invalid values (negative, NaN, non-integer, etc.)
    • Functionality tests for objects, arrays, Map, and Set

Test Results

All 237 tests pass.


When breakLength is set to Infinity, output will always be single-line regardless of the indent option.
This matches the behavior of Node.js `util.inspect({ breakLength: Infinity })`.

Fixes inspect-js#47

- Add validation for breakLength option (positive integer or Infinity)
- When breakLength is Infinity, skip indentation to force single-line output
- Add tests for validation and functionality
- Update README documentation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@abhu85
Copy link
Copy Markdown
Author

abhu85 commented Mar 3, 2026

Friendly ping for review when you have a chance.

Note: This PR was generated with Claude Code. If you're not comfortable with AI-generated contributions, please let me know and I'll close it - no hard feelings. The implementation is straightforward enough that a maintainer could do it directly if preferred.

@abhu85
Copy link
Copy Markdown
Author

abhu85 commented Mar 3, 2026

Maintainer edits are now enabled. Could you re-run the CI checks? Thanks!

@abhu85 abhu85 closed this Mar 9, 2026
@abhu85 abhu85 reopened this Mar 9, 2026
Copy link
Copy Markdown
Member

@ljharb ljharb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t see any tests for a finite breakLength. Also, why is zero disallowed?

@abhu85
Copy link
Copy Markdown
Author

abhu85 commented Mar 9, 2026

Thanks for the review @ljharb!

Re: Why is zero disallowed?
You're right - I was overly restrictive. I've updated the validation to allow breakLength: 0, which in Node.js util.inspect means "always break" (maximum vertical output). Fixed in ad8539c.

Re: Tests for finite breakLength
Added tests in ad8539c that verify:

  • breakLength: 0, 80, and 120 are accepted without throwing
  • Finite breakLength values with indent still produce multi-line output (as expected)

Note: The current implementation focuses on the Infinity case per issue #47. Finite breakLength values are accepted but don't implement actual line-length measurement - they behave the same as the default (multi-line when indent is set). Full line-length-based breaking would be a larger change. Let me know if you'd like me to implement that as well.

@ljharb
Copy link
Copy Markdown
Member

ljharb commented Mar 9, 2026

If there’s only two modes - multi and single line - then surely it should just be a boolean?

@abhu85
Copy link
Copy Markdown
Author

abhu85 commented Mar 9, 2026

@Ijharb Good point. My implementation currently only distinguishes:

  • breakLength: Infinity → force single-line
  • Any finite value → default multi-line behavior (when indent is set)

I don't actually measure output length against a finite threshold.

The original issue #47 requested breakLength specifically to match Node.js util.inspect API, but if that level of compatibility isn't needed, a simple boolean like singleLine: true would be cleaner.

What's your preference?

  1. Keep breakLength - for future Node.js util.inspect compatibility (even if only Infinity is implemented now)
  2. Switch to boolean - e.g., singleLine: true (simpler, but diverges from util.inspect API)

@ljharb
Copy link
Copy Markdown
Member

ljharb commented Mar 10, 2026

We should indeed be matching util.inspect. We shouldn't add the option until we have full compatibility.

@abhu85
Copy link
Copy Markdown
Author

abhu85 commented Mar 14, 2026

@ljharb Updated in 959da36breakLength now works as a real threshold, not just an Infinity special case.

How it works:

  • For each container (object, array, Map, Set), the single-line representation is generated first
  • If its length exceeds breakLength, the output breaks into multi-line (when indent is set)
  • This applies recursively: inner objects stay single-line if they fit, even when the outer breaks

Examples:

inspect({a: {b: 1}, c: 2}, {indent: 2, breakLength: 30})
// '{ a: { b: 1 }, c: 2 }'  (22 chars <= 30, fits)

inspect({a: {b: 1}, c: 2}, {indent: 2, breakLength: 10})
// '{\n  a: { b: 1 },\n  c: 2\n}'  (outer breaks, inner 8 chars <= 10 fits)

inspect({a: {b: 1}, c: 2}, {indent: 2, breakLength: 5})
// both levels break (inner 8 > 5)

Backward compatible: When breakLength is not provided, indent behavior is unchanged — objects always go multi-line, arrays stay single-line unless elements contain newlines.

All 256 tests pass.

ljharb

This comment was marked as outdated.

ljharb

This comment was marked as outdated.

Copy link
Copy Markdown
Member

@ljharb ljharb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The feature works and the tests are comprehensive, but there are some issues to address before merging.

@abhu85
Copy link
Copy Markdown
Author

abhu85 commented Mar 14, 2026

Thanks for the detailed review! I've addressed all 6 issues:

1. Performance regression (fixed)

Gated singleLine computation behind hasBreakLength for arrays, objects, and collections. The $join call now only runs when needed:

if (indent && !singleLineValues(xs)) {
    return '[' + indentedJoin(xs, indent) + ']';
}
var singleLine = '[ ' + $join.call(xs, ', ') + ' ]';
if (indent && hasBreakLength && singleLine.length > breakLength) {
    return '[' + indentedJoin(xs, indent) + ']';
}
return singleLine;

2. Documentation of semantic change (fixed)

Added explicit note in README:

Note: When breakLength is specified, objects will also stay single-line if they fit within the threshold (unlike the default behavior where objects always go multi-line with indent)

3. Function parameters (fixed)

Refactored collectionOf from 6 positional params to 4 using an options object:

function collectionOf(type, size, entries, opts)
// opts: { breakOpts: { has, len }, indent }

4 & 5. Comment typos (fixed)

  • 28 → 27 chars
  • 18 → 17 chars
  • 14 → 15 chars

6. README formatting (fixed)

Reformatted as bulleted list similar to other options.

All 260 tests pass!

@ljharb ljharb force-pushed the feat/breaklength-infinity branch from 4236618 to 5832fbb Compare March 15, 2026 03:10
@ljharb
Copy link
Copy Markdown
Member

ljharb commented Mar 15, 2026

I've rebased this with a few tweaks. Note that the Map test checks breakLength: 0 and breakLength: Infinity but doesn't test a finite threshold boundary (eg, the exact length where single-line transitions to multi-line). The object and array tests do this already, so it'd be nice to mirror that here (probably for Set also)

Add tests that verify the exact transition point from single-line to
multi-line output for Map and Set, mirroring the existing object and
array threshold tests:

- Map (28 chars): breakLength 28 → single-line, 27 → multi-line
- Set (17 chars): breakLength 17 → single-line, 16 → multi-line

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@abhu85
Copy link
Copy Markdown
Author

abhu85 commented Mar 16, 2026

Added threshold boundary tests for Map and Set in 27e8f42:

  • Map (28 chars): breakLength: 28 → single-line, breakLength: 27 → multi-line
  • Set (17 chars): breakLength: 17 → single-line, breakLength: 16 → multi-line

These now mirror the object and array threshold tests. All 264 tests pass.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

want to support breakLength: Infinity

2 participants