Test-MockFile

 view release on metacpan or  search on metacpan

lib/Test/MockFile/FileHandle.pm  view on Meta::CPAN

    # Fixed-record mode: $/ = \N — read exactly N bytes
    if ( ref $/ ) {
        my $reclen = ${ $/ } + 0;
        return undef if $tell >= $len;
        my $remaining = $len - $tell;
        my $read_len  = $reclen < $remaining ? $reclen : $remaining;
        $self->{'tell'} = $tell + $read_len;
        return substr( $contents, $tell, $read_len );
    }

    # Paragraph mode: $/ = '' — read paragraphs separated by blank lines
    if ( $/ eq '' ) {
        my $pos = $tell;

        # Skip leading newlines
        while ( $pos < $len && substr( $contents, $pos, 1 ) eq "\n" ) {
            $pos++;
        }
        return undef if $pos >= $len;

        my $start    = $pos;

t/readline_modes.t  view on Meta::CPAN

    open( my $fh, '<', $filename ) or die "open: $!";
    local $/ = \100;
    my $r1 = <$fh>;
    my $r2 = <$fh>;
    is( $r1, "small", "Record larger than file returns all contents" );
    is( $r2, undef,   "Second read returns undef" );
    close $fh;
}

# ============================================================
# Paragraph mode: $/ = ''
# ============================================================

note "-------------- PARAGRAPH MODE (\$/ = '') --------------";

{
    note "Two paragraphs separated by blank line";
    my $mock = Test::MockFile->file( $filename, "para1 line1\npara1 line2\n\npara2 line1\n" );
    open( my $fh, '<', $filename ) or die "open: $!";
    local $/ = '';
    my $p1 = <$fh>;
    my $p2 = <$fh>;
    my $p3 = <$fh>;
    is( $p1, "para1 line1\npara1 line2\n\n", "First paragraph with collapsed \\n\\n" );
    is( $p2, "para2 line1\n",                "Second paragraph (last, no trailing blank)" );
    is( $p3, undef,                          "Third read returns undef (EOF)" );
    close $fh;
}

{
    note "Multiple blank lines between paragraphs (collapsed)";
    my $mock = Test::MockFile->file( $filename, "first\n\n\n\nsecond\n" );
    open( my $fh, '<', $filename ) or die "open: $!";
    local $/ = '';
    my $p1 = <$fh>;
    my $p2 = <$fh>;
    is( $p1, "first\n\n",  "First paragraph with collapsed separator" );
    is( $p2, "second\n",   "Second paragraph after multiple blank lines" );
    close $fh;
}

{
    note "Leading blank lines are skipped";
    my $mock = Test::MockFile->file( $filename, "\n\n\nhello\n\nworld\n" );
    open( my $fh, '<', $filename ) or die "open: $!";
    local $/ = '';
    my $p1 = <$fh>;
    my $p2 = <$fh>;
    my $p3 = <$fh>;
    is( $p1, "hello\n\n",  "First paragraph (leading blanks skipped)" );
    is( $p2, "world\n",    "Second paragraph" );
    is( $p3, undef,        "EOF" );
    close $fh;
}

{
    note "Single paragraph, no blank lines";
    my $mock = Test::MockFile->file( $filename, "just one\nparagraph\n" );
    open( my $fh, '<', $filename ) or die "open: $!";
    local $/ = '';
    my $p1 = <$fh>;
    my $p2 = <$fh>;
    is( $p1, "just one\nparagraph\n", "Single paragraph returned whole" );
    is( $p2, undef,                   "EOF" );
    close $fh;
}

{
    note "Paragraph mode in list context";
    my $mock = Test::MockFile->file( $filename, "p1\n\np2\n\np3\n" );
    open( my $fh, '<', $filename ) or die "open: $!";
    local $/ = '';
    my @paras = <$fh>;
    is( \@paras, [ "p1\n\n", "p2\n\n", "p3\n" ], "List context returns all paragraphs" );
    close $fh;
}

{
    note "File is only blank lines";
    my $mock = Test::MockFile->file( $filename, "\n\n\n" );
    open( my $fh, '<', $filename ) or die "open: $!";
    local $/ = '';
    my $p1 = <$fh>;
    is( $p1, undef, "File with only newlines returns undef in paragraph mode" );
    close $fh;
}

{
    note "Paragraph without trailing newline";
    my $mock = Test::MockFile->file( $filename, "abc\n\ndef" );
    open( my $fh, '<', $filename ) or die "open: $!";
    local $/ = '';
    my $p1 = <$fh>;
    my $p2 = <$fh>;
    is( $p1, "abc\n\n", "First paragraph ends with collapsed \\n\\n" );
    is( $p2, "def",     "Last paragraph without trailing newline" );
    close $fh;
}

# ============================================================
# Custom multi-character record separator
# ============================================================



( run in 0.642 second using v1.01-cache-2.11-cpan-ac8be02dad9 )