Catalyst-Seal

 view release on metacpan or  search on metacpan

t/70-finalize.t  view on Meta::CPAN

# ran first decides for the other: a response with a manual charset gets its
# body encoded a second time. The memo keys on the raw header instead.
#
# Driving them in both orders, in one process, is the whole point. A single
# order can pass with the bug present.
{
    Catalyst::Seal::Finalize::_clear();
    my $plain  = res('ct=text/plain&kind=wide');
    my $latin  = res('ct=text/plain%3B%20charset=ISO-8859-1&kind=wide');

    is($plain->{headers}{'content-type'}, 'text/plain; charset=UTF-8',
        'no charset: encoded and the charset appended');
    is($latin->{headers}{'content-type'}, 'text/plain; charset=ISO-8859-1',
        'a manual charset is left alone, after the plain one was cached');

    Catalyst::Seal::Finalize::_clear();
    my $latin2 = res('ct=text/plain%3B%20charset=ISO-8859-1&kind=wide');
    my $plain2 = res('ct=text/plain&kind=wide');

    is($latin2->{headers}{'content-type'}, 'text/plain; charset=ISO-8859-1',
        'and in the other order');
    is($plain2->{headers}{'content-type'}, 'text/plain; charset=UTF-8',
        'the plain one is still encoded after the manual one was cached');

    isnt($latin->{body}, $plain->{body},
        'the two bodies really did take different paths');
}

# ---------------------------------------------------------- the encodable set

{
    Catalyst::Seal::Finalize::_clear();

    is(res('ct=application/json&kind=wide')->{headers}{'content-type'},
        'application/json', 'a non-encodable type is left alone');
    is(res('ct=text/plain&cenc=gzip&kind=wide')->{headers}{'content-type'},
        'text/plain', 'a content-encoding other than identity suppresses encoding');
    is(res('ct=text/plain&cenc=identity&kind=wide')->{headers}{'content-type'},
        'text/plain; charset=UTF-8', 'identity does not');

    # Distinct inputs, distinct entries: a memo that collapsed them would have
    # failed the assertions above, and this says so directly.
    cmp_ok(Catalyst::Seal::Finalize::memo_size(), '>=', 3,
        'each distinct input got its own entry');
}

# ------------------------------------------------------- runtime encoding

t/70-finalize.t  view on Meta::CPAN

{
    Catalyst::Seal::Finalize::_clear();

    my $utf8 = res('ct=text/plain&kind=wide&encoding=UTF-8');
    my $none = res('ct=text/plain&kind=wide&encoding=clear');
    # kind=latin, because the snowman in kind=wide does not map to Latin-1 and
    # the encoder dies. Stock dies the same way; that is covered in the parity
    # table, and is not what this block is about.
    my $l1   = res('ct=text/plain&kind=latin&encoding=ISO-8859-1');

    is($utf8->{headers}{'content-type'}, 'text/plain; charset=UTF-8',
        'UTF-8 encodes');
    is($none->{headers}{'content-type'}, 'text/plain',
        'clear_encoding suppresses encoding, after UTF-8 was cached');
    is($l1->{headers}{'content-type'}, 'text/plain; charset=ISO-8859-1',
        'a different encoding is not served the UTF-8 answer');

    isnt($utf8->{body}, $none->{body}, 'and the bodies differ accordingly');
}

# -------------------------------------------------------------- body shapes

{
    Catalyst::Seal::Finalize::_clear();
    is(res('ct=text/plain&kind=array')->{headers}{'content-type'}, 'text/plain',
        'an arrayref body is not encoded');
    is(res('ct=text/plain&kind=fh')->{headers}{'content-type'}, 'text/plain',
        'a filehandle body is not encoded');
    is(res('ct=text/plain&kind=undef')->{headers}{'content-type'}, 'text/plain',
        'an absent body is not encoded');
    is(res('ct=text/plain&kind=ascii')->{body}, 'plain ascii',
        'an ascii body survives encoding unchanged');
}

# --------------------------------------------------------------------- cap

{
    local $Catalyst::Seal::Finalize::MAX_KEYS = 4;
    Catalyst::Seal::Finalize::_clear();

    res("ct=text/plain%3B%20x=$_&kind=wide") for 1 .. 100;

    cmp_ok(Catalyst::Seal::Finalize::memo_size(), '<=', 4,
        'the decision memo stopped growing at the cap');
    cmp_ok(Catalyst::Seal::Finalize::capped(), '>', 0, 'and said so');

    # Still correct past the cap, which is the point of capping rather than
    # clearing.
    is(res('ct=text/plain%3B%20charset=ISO-8859-1&kind=wide')->{headers}{'content-type'},
        'text/plain; charset=ISO-8859-1', 'decisions are still right past the cap');
}
Catalyst::Seal::Finalize::_clear();

# ----------------------------------------------------------------- DESTROY

{
    ok(
        Catalyst::Response->can('DESTROY') == \&Catalyst::Seal::Finalize::_response_destroy,
        'the response destructor is the eval version',



( run in 3.584 seconds using v1.01-cache-2.11-cpan-800906f7e73 )