Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package perl-Mojolicious for openSUSE:Factory checked in at 2023-06-03 00:06:56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/perl-Mojolicious (Old) and /work/SRC/openSUSE:Factory/.perl-Mojolicious.new.15902 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-Mojolicious" Sat Jun 3 00:06:56 2023 rev:171 rq:1090343 version:9.32 Changes: -------- --- /work/SRC/openSUSE:Factory/perl-Mojolicious/perl-Mojolicious.changes 2023-01-04 17:55:05.127059617 +0100 +++ /work/SRC/openSUSE:Factory/.perl-Mojolicious.new.15902/perl-Mojolicious.changes 2023-06-03 00:07:10.705972897 +0200 @@ -1,0 +2,12 @@ +Tue May 9 03:06:47 UTC 2023 - Tina Müller <timueller+p...@suse.de> + +- updated to 9.32 + see /usr/share/doc/packages/perl-Mojolicious/Changes + + 9.32 2022-05-09 + - Improved file and line number details in async/await exceptions. (batman) + - Fixed various CSS selector equation bugs in Mojo::DOM::CSS. (mauke) + - Fixed exceptions being added to the stash for formats other than HTML. (rawleyfowler) + - Fixed context sensitivity issue. (Grinnz) + +------------------------------------------------------------------- Old: ---- Mojolicious-9.31.tar.gz New: ---- Mojolicious-9.32.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ perl-Mojolicious.spec ++++++ --- /var/tmp/diff_new_pack.GcPORs/_old 2023-06-03 00:07:11.637978400 +0200 +++ /var/tmp/diff_new_pack.GcPORs/_new 2023-06-03 00:07:11.641978424 +0200 @@ -1,7 +1,7 @@ # # spec file for package perl-Mojolicious # -# Copyright (c) 2022 SUSE LLC +# Copyright (c) 2023 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,7 +18,7 @@ %define cpan_name Mojolicious Name: perl-Mojolicious -Version: 9.31 +Version: 9.32 Release: 0 License: Artistic-2.0 Summary: Real-time web framework @@ -45,7 +45,8 @@ %prep %autosetup -n %{cpan_name}-%{version} -find . -type f ! -path "*/t/*" ! -name "*.pl" ! -path "*/bin/*" ! -path "*/script/*" ! -name "configure" -print0 | xargs -0 chmod 644 + +find . -type f ! -path "*/t/*" ! -name "*.pl" ! -path "*/bin/*" ! -path "*/script/*" ! -path "*/scripts/*" ! -name "configure" -print0 | xargs -0 chmod 644 %build perl Makefile.PL INSTALLDIRS=vendor ++++++ Mojolicious-9.31.tar.gz -> Mojolicious-9.32.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-9.31/Changes new/Mojolicious-9.32/Changes --- old/Mojolicious-9.31/Changes 2022-12-21 01:34:34.000000000 +0100 +++ new/Mojolicious-9.32/Changes 2023-05-09 00:08:22.000000000 +0200 @@ -1,4 +1,10 @@ +9.32 2022-05-09 + - Improved file and line number details in async/await exceptions. (batman) + - Fixed various CSS selector equation bugs in Mojo::DOM::CSS. (mauke) + - Fixed exceptions being added to the stash for formats other than HTML. (rawleyfowler) + - Fixed context sensitivity issue. (Grinnz) + 9.31 2022-12-21 - This release contains fixes for security issues, everybody should upgrade! - Removed experimental status from links method in Mojo::Headers. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-9.31/META.json new/Mojolicious-9.32/META.json --- old/Mojolicious-9.31/META.json 2022-12-21 01:35:27.000000000 +0100 +++ new/Mojolicious-9.32/META.json 2023-05-09 00:09:30.000000000 +0200 @@ -64,6 +64,6 @@ "web" : "https://web.libera.chat/#mojo" } }, - "version" : "9.31", + "version" : "9.32", "x_serialization_backend" : "JSON::PP version 4.07" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-9.31/META.yml new/Mojolicious-9.32/META.yml --- old/Mojolicious-9.31/META.yml 2022-12-21 01:35:27.000000000 +0100 +++ new/Mojolicious-9.32/META.yml 2023-05-09 00:09:30.000000000 +0200 @@ -35,5 +35,5 @@ homepage: https://mojolicious.org license: http://www.opensource.org/licenses/artistic-license-2.0 repository: https://github.com/mojolicious/mojo.git -version: '9.31' +version: '9.32' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-9.31/lib/Mojo/DOM/CSS.pm new/Mojolicious-9.32/lib/Mojo/DOM/CSS.pm --- old/Mojolicious-9.31/lib/Mojo/DOM/CSS.pm 2022-06-14 13:31:51.000000000 +0200 +++ new/Mojolicious-9.32/lib/Mojo/DOM/CSS.pm 2023-03-08 19:43:29.000000000 +0100 @@ -117,11 +117,8 @@ # ":nth-*" (with An+B notation) $args = _equation($args) if $name =~ /^nth-/; - # ":first-*" (rewrite to ":nth-*") - ($name, $args) = ("nth-$1", [0, 1]) if $name =~ /^first-(.+)$/; - - # ":last-*" (rewrite to ":nth-*") - ($name, $args) = ("nth-$name", [-1, 1]) if $name =~ /^last-/; + # ":first-*", ":last-*" (rewrite to ":nth-(last-)*") + ($name, $args) = ("nth-$+", [0, 1]) if $name =~ /^(?:first-(.+)|(last-.+))$/; push @$last, ['pc', $name, $args]; } @@ -144,7 +141,7 @@ return [0, 0] unless my $equation = shift; # "even" - return [2, 2] if $equation =~ /^\s*even\s*$/i; + return [2, 0] if $equation =~ /^\s*even\s*$/i; # "odd" return [2, 1] if $equation =~ /^\s*odd\s*$/i; @@ -241,13 +238,16 @@ if (ref $args) { my $type = $class eq 'nth-of-type' || $class eq 'nth-last-of-type' ? $current->[1] : undef; my @siblings = @{_siblings($current, $type)}; - @siblings = reverse @siblings if $class eq 'nth-last-child' || $class eq 'nth-last-of-type'; - + my $index; for my $i (0 .. $#siblings) { - next if (my $result = $args->[0] * $i + $args->[1]) < 1; - return undef unless my $sibling = $siblings[$result - 1]; - return 1 if $sibling eq $current; + $index = $i, last if $siblings[$i] eq $current; } + $index = $#siblings - $index if $class eq 'nth-last-child' || $class eq 'nth-last-of-type'; + $index++; + + my $delta = $index - $args->[1]; + return 1 if $delta == 0; + return $args->[0] != 0 && ($delta < 0) == ($args->[0] < 0) && $delta % $args->[0] == 0; } # Everything else diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-9.31/lib/Mojo/IOLoop/Client.pm new/Mojolicious-9.32/lib/Mojo/IOLoop/Client.pm --- old/Mojolicious-9.31/lib/Mojo/IOLoop/Client.pm 2022-06-14 13:31:51.000000000 +0200 +++ new/Mojolicious-9.32/lib/Mojo/IOLoop/Client.pm 2023-04-27 22:33:00.000000000 +0200 @@ -10,13 +10,13 @@ use Socket qw(IPPROTO_TCP SOCK_STREAM TCP_NODELAY); # Non-blocking name resolution requires Net::DNS::Native -use constant NNR => $ENV{MOJO_NO_NNR} ? 0 : eval { require Net::DNS::Native; Net::DNS::Native->VERSION('0.15'); 1 }; +use constant NNR => $ENV{MOJO_NO_NNR} ? 0 : !!eval { require Net::DNS::Native; Net::DNS::Native->VERSION('0.15'); 1 }; my $NDN; # SOCKS support requires IO::Socket::Socks use constant SOCKS => $ENV{MOJO_NO_SOCKS} ? 0 - : eval { require IO::Socket::Socks; IO::Socket::Socks->VERSION('0.64'); 1 }; + : !!eval { require IO::Socket::Socks; IO::Socket::Socks->VERSION('0.64'); 1 }; use constant READ => SOCKS ? IO::Socket::Socks::SOCKS_WANT_READ() : 0; use constant WRITE => SOCKS ? IO::Socket::Socks::SOCKS_WANT_WRITE() : 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-9.31/lib/Mojo/IOLoop/TLS.pm new/Mojolicious-9.32/lib/Mojo/IOLoop/TLS.pm --- old/Mojolicious-9.31/lib/Mojo/IOLoop/TLS.pm 2022-06-14 13:31:51.000000000 +0200 +++ new/Mojolicious-9.32/lib/Mojo/IOLoop/TLS.pm 2023-04-27 22:33:00.000000000 +0200 @@ -6,7 +6,7 @@ use Scalar::Util qw(weaken); # TLS support requires IO::Socket::SSL -use constant TLS => $ENV{MOJO_NO_TLS} ? 0 : eval { require IO::Socket::SSL; IO::Socket::SSL->VERSION('2.009'); 1 }; +use constant TLS => $ENV{MOJO_NO_TLS} ? 0 : !!eval { require IO::Socket::SSL; IO::Socket::SSL->VERSION('2.009'); 1 }; use constant READ => TLS ? IO::Socket::SSL::SSL_WANT_READ() : 0; use constant WRITE => TLS ? IO::Socket::SSL::SSL_WANT_WRITE() : 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-9.31/lib/Mojo/JSON.pm new/Mojolicious-9.32/lib/Mojo/JSON.pm --- old/Mojolicious-9.31/lib/Mojo/JSON.pm 2022-06-14 13:31:51.000000000 +0200 +++ new/Mojolicious-9.32/lib/Mojo/JSON.pm 2023-04-27 22:33:00.000000000 +0200 @@ -10,7 +10,7 @@ # For better performance Cpanel::JSON::XS is required use constant JSON_XS => $ENV{MOJO_NO_JSON_XS} ? 0 - : eval { require Cpanel::JSON::XS; Cpanel::JSON::XS->VERSION('4.09'); 1 }; + : !!eval { require Cpanel::JSON::XS; Cpanel::JSON::XS->VERSION('4.09'); 1 }; our @EXPORT_OK = qw(decode_json encode_json false from_json j to_json true); @@ -49,7 +49,7 @@ sub j { return encode_json($_[0]) if ref $_[0] eq 'ARRAY' || ref $_[0] eq 'HASH'; - return eval { decode_json($_[0]) }; + return scalar eval { decode_json($_[0]) }; } sub to_json { _encode_value(shift) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-9.31/lib/Mojo/Promise.pm new/Mojolicious-9.32/lib/Mojo/Promise.pm --- old/Mojolicious-9.31/lib/Mojo/Promise.pm 2022-10-31 14:36:40.000000000 +0100 +++ new/Mojolicious-9.32/lib/Mojo/Promise.pm 2023-03-08 19:49:14.000000000 +0100 @@ -1,7 +1,7 @@ package Mojo::Promise; use Mojo::Base -base; -use Carp qw(carp); +use Carp qw(carp croak); use Mojo::Exception; use Mojo::IOLoop; use Scalar::Util qw(blessed); @@ -18,8 +18,9 @@ sub AWAIT_GET { my $self = shift; my @results = @{$self->{results} // []}; - die $results[0] unless $self->{status} eq 'resolve'; - return wantarray ? @results : $results[0]; + return wantarray ? @results : $results[0] if $self->{status} eq 'resolve'; + die $results[0] if ref $results[0] || $results[0] =~ m!\n!; + croak $results[0]; } sub AWAIT_IS_CANCELLED {undef} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-9.31/lib/Mojo/Util.pm new/Mojolicious-9.32/lib/Mojo/Util.pm --- old/Mojolicious-9.31/lib/Mojo/Util.pm 2022-11-23 01:28:59.000000000 +0100 +++ new/Mojolicious-9.32/lib/Mojo/Util.pm 2023-04-27 22:33:00.000000000 +0200 @@ -22,7 +22,7 @@ use Unicode::Normalize (); # Check for monotonic clock support -use constant MONOTONIC => eval { !!Time::HiRes::clock_gettime(Time::HiRes::CLOCK_MONOTONIC()) }; +use constant MONOTONIC => !!eval { Time::HiRes::clock_gettime(Time::HiRes::CLOCK_MONOTONIC()) }; # Punycode bootstring parameters use constant { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-9.31/lib/Mojolicious/Guides/Cookbook.pod new/Mojolicious-9.32/lib/Mojolicious/Guides/Cookbook.pod --- old/Mojolicious-9.31/lib/Mojolicious/Guides/Cookbook.pod 2022-12-10 18:55:56.000000000 +0100 +++ new/Mojolicious-9.32/lib/Mojolicious/Guides/Cookbook.pod 2023-02-01 21:11:01.000000000 +0100 @@ -1799,10 +1799,10 @@ $self->renderer->paths->[0] = $self->home->child('templates'); # Exclude author commands - $self->commands->namespaces(['Mojolicious::Commands']); + $self->commands->namespaces(['Mojolicious::Command']); my $r = $self->routes; - $r->get('/welcome')->to('example#welcome'); + $r->get('/')->to('example#welcome'); } 1; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-9.31/lib/Mojolicious/Guides/Routing.pod new/Mojolicious-9.32/lib/Mojolicious/Guides/Routing.pod --- old/Mojolicious-9.31/lib/Mojolicious/Guides/Routing.pod 2022-06-14 13:31:51.000000000 +0200 +++ new/Mojolicious-9.32/lib/Mojolicious/Guides/Routing.pod 2023-04-27 22:33:00.000000000 +0200 @@ -256,6 +256,10 @@ $self->stash(mymessage => 'Welcome'); } +You can use L<Mojolicious/"defaults"> to set default stash values that will be available everywhere in the application. + + $app->defaults(mymessage => 'Howdy'); + For a full list of reserved stash values see L<Mojolicious::Controller/"stash">. =head2 Nested routes diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-9.31/lib/Mojolicious/Plugin/DefaultHelpers.pm new/Mojolicious-9.32/lib/Mojolicious/Plugin/DefaultHelpers.pm --- old/Mojolicious-9.31/lib/Mojolicious/Plugin/DefaultHelpers.pm 2022-09-10 17:04:08.000000000 +0200 +++ new/Mojolicious-9.32/lib/Mojolicious/Plugin/DefaultHelpers.pm 2023-05-09 00:06:24.000000000 +0200 @@ -90,6 +90,11 @@ return Mojo::ByteStream->new($hash->{$name} // ''); } +sub _convert_to_exception { + my $e = shift; + return (blessed $e && $e->isa('Mojo::Exception')) ? $e : Mojo::Exception->new($e); +} + sub _csrf_token { $_[0]->session->{csrf_token} ||= hmac_sha1_sum($$ . steady_time . rand, $_[0]->app->secrets->[0]) } sub _current_route { @@ -100,7 +105,7 @@ sub _development { my ($page, $c, $e) = @_; - $c->helpers->log->error(($e = _is_e($e) ? $e : Mojo::Exception->new($e))->inspect) if $page eq 'exception'; + $c->helpers->log->error(($e = _convert_to_exception($e))->inspect) if $page eq 'exception'; # Filtered stash snapshot my $stash = $c->stash; @@ -187,8 +192,6 @@ return $c; } -sub _is_e { blessed $_[0] && $_[0]->isa('Mojo::Exception') } - sub _is_fresh { my ($c, %options) = @_; return $c->app->static->is_fresh($c, \%options); @@ -196,6 +199,7 @@ sub _json_exception { my ($c, $e) = @_; + $c->stash->{exception} = _convert_to_exception($e); return $c->render(json => {error => $e}, status => 500) if $c->app->mode eq 'development'; return $c->render(json => {error => 'Internal Server Error'}, status => 500); } @@ -242,9 +246,7 @@ } ); - # Unknown length (fall back to connection close) - $source_res->once(finish => sub { $content->$write('') and $tx->resume }) - unless length($headers->content_length // ''); + $source_res->once(finish => sub { $content->$write('') and $tx->resume }); } ); weaken $source_tx; @@ -317,6 +319,7 @@ sub _txt_exception { my ($c, $e) = @_; + $c->stash->{exception} = _convert_to_exception($e); return $c->render(text => $e, format => 'txt', status => 500) if $c->app->mode eq 'development'; return $c->render(text => 'Internal Server Error', format => 'txt', status => 500); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-9.31/lib/Mojolicious/resources/templates/mojo/debug.html.ep new/Mojolicious-9.32/lib/Mojolicious/resources/templates/mojo/debug.html.ep --- old/Mojolicious-9.31/lib/Mojolicious/resources/templates/mojo/debug.html.ep 2022-12-18 20:20:49.000000000 +0100 +++ new/Mojolicious-9.32/lib/Mojolicious/resources/templates/mojo/debug.html.ep 2023-04-28 00:37:27.000000000 +0200 @@ -306,7 +306,7 @@ <b>Free</b> and <b>Open Source</b>. </div> <div class="col-sm align-self-center text-center mojo-copy"> - <i class="far fa-copyright"></i> 2008-2022 Sebastian Riedel and the + <i class="far fa-copyright"></i> 2008-2023 Sebastian Riedel and the <a href="https://docs.mojolicious.org/Mojolicious#AUTHORS">Mojolicious contributors</a>. </div> <div class="col-sm align-self-center text-center mojo-social"> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-9.31/lib/Mojolicious.pm new/Mojolicious-9.32/lib/Mojolicious.pm --- old/Mojolicious-9.31/lib/Mojolicious.pm 2022-12-21 01:30:55.000000000 +0100 +++ new/Mojolicious-9.32/lib/Mojolicious.pm 2023-05-09 00:07:21.000000000 +0200 @@ -57,7 +57,7 @@ has validator => sub { Mojolicious::Validator->new }; our $CODENAME = 'Waffle'; -our $VERSION = '9.31'; +our $VERSION = '9.32'; sub BUILD_DYNAMIC { my ($class, $method, $dyn_methods) = @_; @@ -752,7 +752,7 @@ =head2 Mojolicious Artwork - Copyright (C) 2010-2022, Sebastian Riedel. + Copyright (C) 2010-2023, Sebastian Riedel. Licensed under the CC-SA License, Version 4.0 L<http://creativecommons.org/licenses/by-sa/4.0>. @@ -1030,6 +1030,8 @@ Leon Brocard +Lukas Mai + Magnus Holm Maik Fischer @@ -1100,6 +1102,8 @@ Randal Schwartz +Rawley Fowler + Richard Elberger Rick Delaney @@ -1192,7 +1196,7 @@ =head1 COPYRIGHT AND LICENSE -Copyright (C) 2008-2022, Sebastian Riedel and others. +Copyright (C) 2008-2023, Sebastian Riedel and others. This program is free software, you can redistribute it and/or modify it under the terms of the Artistic License version 2.0. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-9.31/t/mojo/dom.t new/Mojolicious-9.32/t/mojo/dom.t --- old/Mojolicious-9.31/t/mojo/dom.t 2022-12-10 23:30:41.000000000 +0100 +++ new/Mojolicious-9.32/t/mojo/dom.t 2023-03-08 19:43:33.000000000 +0100 @@ -1040,28 +1040,28 @@ is_deeply \@li, ['F'], 'found third last li element'; @li = (); $dom->find('li:nth-child(1n+0)')->each(sub { push @li, shift->text }); - is_deeply \@li, [qw(A B C D E F G)], 'found all li elements'; + is_deeply \@li, [qw(A B C D E F G H)], 'found all li elements'; @li = (); $dom->find('li:nth-child(1n-0)')->each(sub { push @li, shift->text }); - is_deeply \@li, [qw(A B C D E F G)], 'found all li elements'; + is_deeply \@li, [qw(A B C D E F G H)], 'found all li elements'; @li = (); $dom->find('li:nth-child(n+0)')->each(sub { push @li, shift->text }); - is_deeply \@li, [qw(A B C D E F G)], 'found all li elements'; + is_deeply \@li, [qw(A B C D E F G H)], 'found all li elements'; @li = (); $dom->find('li:nth-child(n)')->each(sub { push @li, shift->text }); - is_deeply \@li, [qw(A B C D E F G)], 'found all li elements'; + is_deeply \@li, [qw(A B C D E F G H)], 'found all li elements'; @li = (); $dom->find('li:nth-child(n+0)')->each(sub { push @li, shift->text }); - is_deeply \@li, [qw(A B C D E F G)], 'found all li elements'; + is_deeply \@li, [qw(A B C D E F G H)], 'found all li elements'; @li = (); $dom->find('li:NTH-CHILD(N+0)')->each(sub { push @li, shift->text }); - is_deeply \@li, [qw(A B C D E F G)], 'found all li elements'; + is_deeply \@li, [qw(A B C D E F G H)], 'found all li elements'; @li = (); $dom->find('li:Nth-Child(N+0)')->each(sub { push @li, shift->text }); - is_deeply \@li, [qw(A B C D E F G)], 'found all li elements'; + is_deeply \@li, [qw(A B C D E F G H)], 'found all li elements'; @li = (); $dom->find('li:nth-child(n)')->each(sub { push @li, shift->text }); - is_deeply \@li, [qw(A B C D E F G)], 'found all li elements'; + is_deeply \@li, [qw(A B C D E F G H)], 'found all li elements'; @li = (); $dom->find('li:nth-child(0n+1)')->each(sub { push @li, shift->text }); is_deeply \@li, [qw(A)], 'found first li element'; @@ -1102,19 +1102,19 @@ is_deeply \@e, [qw(A E H)], 'found all odd li elements'; @e = (); $dom->find('ul li:not(:first-child, :last-child)')->each(sub { push @e, shift->text }); - is_deeply \@e, [qw(C E F H)], 'found all odd li elements'; + is_deeply \@e, [qw(C E F H)], 'found all li elements but first/last'; @e = (); $dom->find('ul li:is(:first-child, :last-child)')->each(sub { push @e, shift->text }); - is_deeply \@e, [qw(A I)], 'found all odd li elements'; + is_deeply \@e, [qw(A I)], 'found first/last li elements'; @e = (); $dom->find('li:nth-last-of-type( odd )')->each(sub { push @e, shift->text }); - is_deeply \@e, [qw(C F I)], 'found all odd li elements'; + is_deeply \@e, [qw(C F I)], 'found all odd li elements (counting from end)'; @e = (); $dom->find('p:nth-of-type(odd)')->each(sub { push @e, shift->text }); is_deeply \@e, [qw(B G)], 'found all odd p elements'; @e = (); $dom->find('p:nth-last-of-type(odd)')->each(sub { push @e, shift->text }); - is_deeply \@e, [qw(B G)], 'found all odd li elements'; + is_deeply \@e, [qw(B G)], 'found all odd p elements (counting from end)'; @e = (); $dom->find('ul :nth-child(1)')->each(sub { push @e, shift->text }); is_deeply \@e, ['A'], 'found first child'; @@ -1193,6 +1193,9 @@ @e = (); $dom->find('div div:only-of-type')->each(sub { push @e, shift->text }); is_deeply \@e, [qw(J K)], 'found only child'; + @e = (); + $dom->find('div :nth-child(-n+2)')->each(sub { push @e, shift->text }); + is_deeply \@e, [qw(J Mojo! K)], 'found first two children of each div'; }; subtest 'Links' => sub { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-9.31/t/mojo/promise_async_await.t new/Mojolicious-9.32/t/mojo/promise_async_await.t --- old/Mojolicious-9.31/t/mojo/promise_async_await.t 2022-10-31 14:36:40.000000000 +0100 +++ new/Mojolicious-9.32/t/mojo/promise_async_await.t 2023-03-08 19:49:14.000000000 +0100 @@ -137,6 +137,12 @@ $t->get_ok('/four')->status_is(500)->content_like(qr/this went perfectly/); }; +subtest 'Exception handling with file and line reporting' => sub { + my $error; + reject_p()->catch(sub { $error = shift })->wait; + like $error, qr/^Rejected promise at .*promise_async_await\.t line \d+\.$/, 'right content'; +}; + subtest 'Exception handling without "Unhandled rejected promise" warning' => sub { my ($error, @warn); local $SIG{__WARN__} = sub { push @warn, $_[0] }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-9.31/t/mojolicious/exception_lite_app.t new/Mojolicious-9.32/t/mojolicious/exception_lite_app.t --- old/Mojolicious-9.31/t/mojolicious/exception_lite_app.t 2022-09-10 17:28:46.000000000 +0200 +++ new/Mojolicious-9.32/t/mojolicious/exception_lite_app.t 2023-05-09 00:06:24.000000000 +0200 @@ -302,9 +302,12 @@ ->json_like('/error', qr/dead template!/); $t->get_ok('/does_not_exist')->status_is(404)->content_type_is('application/json;charset=UTF-8') ->json_is({error => 'Not Found'}); - + my $stash; + $t->app->hook(after_dispatch => sub { $stash = shift->stash }); $t->get_ok('/txt/exception')->status_is(500)->header_is('X-Text' => 'txt') ->content_type_is('text/plain;charset=UTF-8')->content_like(qr/Text exception/); + ok $stash->{exception}, 'exception exists in stash'; + isa_ok $stash->{exception}, 'Mojo::Exception', 'is stash exception correct type?'; $t->app->mode('production'); $t->get_ok('/dead_template')->status_is(500)->content_type_is('application/json;charset=UTF-8') @@ -319,9 +322,12 @@ $t->get_ok('/dead_template')->status_is(500)->content_type_is('text/plain;charset=UTF-8') ->content_like(qr/dead template!/); $t->get_ok('/does_not_exist')->status_is(404)->content_type_is('text/plain;charset=UTF-8')->content_is('Not Found'); - + my $stash; + $t->app->hook(after_dispatch => sub { $stash = shift->stash }); $t->get_ok('/txt/exception')->status_is(500)->header_is('X-Text' => 'txt') ->content_type_is('text/plain;charset=UTF-8')->content_like(qr/Text exception/); + ok $stash->{exception}, 'exception exists in stash'; + isa_ok $stash->{exception}, 'Mojo::Exception', 'is stash exception correct type?'; $t->app->mode('production'); $t->get_ok('/dead_template')->status_is(500)->content_type_is('text/plain;charset=UTF-8') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-9.31/t/mojolicious/proxy_app.t new/Mojolicious-9.32/t/mojolicious/proxy_app.t --- old/Mojolicious-9.31/t/mojolicious/proxy_app.t 2022-06-14 13:31:51.000000000 +0200 +++ new/Mojolicious-9.32/t/mojolicious/proxy_app.t 2023-03-08 19:43:37.000000000 +0100 @@ -17,6 +17,26 @@ my $url = Mojo::URL->new("http://127.0.0.1:$port"); my $r = $app->routes; $r->get( + '/size/:code/:length' => {code => 204, length => 0} => sub { + my $c = shift; + my $code = $c->param('code'); + my $length = $c->param('length'); + $c->res->headers->header('X-Mojo-App' => 'Size'); + $c->render(data => 'x' x $length, status => $code); + } +)->name('size'); +$r->get( + '/redirect/:code1/:code2/:length' => {code1 => 302, code2 => 204, length => 0} => sub { + my $c = shift; + my $code1 = $c->param('code1'); + my $code2 = $c->param('code2'); + my $length = $c->param('length'); + $c->res->headers->header('X-Mojo-App' => 'Redirect'); + $c->res->code($code1); + $c->redirect_to($c->url_for('size', {code => $code2, length => $length})->to_abs); + } +)->name('redirect'); +$r->get( '/res1' => sub { my $c = shift; $c->res->headers->header('X-Mojo-App' => 'One'); @@ -69,7 +89,7 @@ get '/proxy1/*target' => sub { my $c = shift; my $target = $c->stash('target'); - $c->proxy->get_p($url->path($target))->catch(sub { + $c->proxy->get_p($url->clone->path($target))->catch(sub { my $err = shift; $c->render(text => "Error: $err", status => 400); }); @@ -102,6 +122,32 @@ my $t = Test::Mojo->new; subtest 'Various response variants' => sub { + $t->get_ok('/proxy1/size/200/2')->status_is(200)->header_is('X-Mojo-App' => 'Size')->header_is('Content-Length' => 2) + ->content_is('xx'); + $t->get_ok('/proxy1/size/200/1')->status_is(200)->header_is('X-Mojo-App' => 'Size')->header_is('Content-Length' => 1) + ->content_is('x'); + $t->get_ok('/proxy1/size/200/0')->status_is(200)->header_is('X-Mojo-App' => 'Size')->header_is('Content-Length' => 0) + ->content_is(''); + $t->get_ok('/proxy1/size/204/0')->status_is(204)->header_is('X-Mojo-App' => 'Size') + ->header_is('Content-Length' => undef)->content_is(''); + $t->get_ok('/proxy1/redirect/304/200/1')->status_is(304)->header_is('X-Mojo-App' => 'Redirect') + ->header_is('Content-Length' => undef)->content_is(''); + $t->get_ok('/proxy1/redirect/302/200/1')->status_is(302)->header_is('X-Mojo-App' => 'Redirect') + ->header_is('Content-Length' => 0)->content_is(''); + $t->get_ok('/proxy1/redirect/301/200/1')->status_is(301)->header_is('X-Mojo-App' => 'Redirect') + ->header_is('Content-Length' => 0)->content_is(''); + $t->get_ok('/proxy1/redirect/304/200/0')->status_is(304)->header_is('X-Mojo-App' => 'Redirect') + ->header_is('Content-Length' => undef)->content_is(''); + $t->get_ok('/proxy1/redirect/302/200/0')->status_is(302)->header_is('X-Mojo-App' => 'Redirect') + ->header_is('Content-Length' => 0)->content_is(''); + $t->get_ok('/proxy1/redirect/301/200/0')->status_is(301)->header_is('X-Mojo-App' => 'Redirect') + ->header_is('Content-Length' => 0)->content_is(''); + $t->get_ok('/proxy1/redirect/304/204/0')->status_is(304)->header_is('X-Mojo-App' => 'Redirect') + ->header_is('Content-Length' => undef)->content_is(''); + $t->get_ok('/proxy1/redirect/302/204/0')->status_is(302)->header_is('X-Mojo-App' => 'Redirect') + ->header_is('Content-Length' => 0)->content_is(''); + $t->get_ok('/proxy1/redirect/301/204/0')->status_is(301)->header_is('X-Mojo-App' => 'Redirect') + ->header_is('Content-Length' => 0)->content_is(''); $t->get_ok('/proxy1/res1')->status_is(200)->header_is('X-Mojo-App' => 'One')->content_is('One!'); $t->get_ok('/proxy1/res2')->status_is(200)->header_is('X-Mojo-App' => 'Two')->content_is('Two!'); $t->get_ok('/proxy1/res3')->status_is(200)->header_is('X-Mojo-App' => 'Three')->header_is('X-Mojo-Method' => 'GET')