Skip to content

feat: add truncate() override for mocked files#223

Merged
toddr merged 2 commits intocpanel:masterfrom
atoomic:koan.atoomic/implement-truncate
Feb 25, 2026
Merged

feat: add truncate() override for mocked files#223
toddr merged 2 commits intocpanel:masterfrom
atoomic:koan.atoomic/implement-truncate

Conversation

@Koan-Bot
Copy link
Contributor

What

Override truncate() for mocked files so it operates on mock contents instead of passing through to the real filesystem.

Why

truncate() was the last major file operation not overridden by Test::MockFile. Calls to truncate($fh, $len) or truncate($path, $len) on mocked files silently hit the real FS — breaking test isolation. Addresses #221.

How

  • CORE::GLOBAL::truncate override via __truncate($$) sub
  • Lookup via _get_file_object (handles both filehandle and path arguments)
  • POSIX-correct: shortens when $length < current, pads with \0 when $length > current
  • Error handling: ENOENT (non-existent), EISDIR (directory), EINVAL (negative length)
  • Registered in file_arg_position_for_command for strict mode
  • Note: &CORE::truncate can't be called via goto, so fallthrough uses direct CORE::truncate() call

Testing

11 subtests in t/truncate.t covering: shorten, extend with nulls, zero-length, no-op same-length, filehandle truncate, sysopen filehandle, ENOENT/EISDIR/EINVAL errors, real file passthrough, and open-then-truncate flow.

🤖 Generated with Claude Code

@Koan-Bot
Copy link
Contributor Author

Rebase: feat: add truncate() override for mocked files

Branch koan.atoomic/implement-truncate has been rebased onto master and force-pushed.

Actions

  • Rebased koan.atoomic/implement-truncate onto origin/master
  • Force-pushed koan.atoomic/implement-truncate to origin

Automated by Kōan

truncate() was not overridden, so calls on mocked files passed through
to the real filesystem. Add CORE::GLOBAL::truncate override that:

- Shortens contents when length < current size
- Pads with null bytes when length > current size
- Returns ENOENT for non-existent mocks, EISDIR for directories,
  EINVAL for negative length
- Falls through to CORE::truncate for non-mocked files
- Registers in file_arg_position_for_command for strict mode support

Note: CORE::truncate does not support goto &CORE::truncate, so the
fallthrough uses explicit CORE::truncate() call.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
A `<<<<<<< HEAD` conflict marker was left behind during the rebase,
causing compilation failure in CI.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@toddr toddr marked this pull request as ready for review February 25, 2026 17:21
@toddr toddr merged commit 49660ce into cpanel:master Feb 25, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants