Hello community,

here is the log from the commit of package perl-Mojolicious for 
openSUSE:Factory checked in at 2019-04-20 17:13:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-Mojolicious (Old)
 and      /work/SRC/openSUSE:Factory/.perl-Mojolicious.new.5536 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "perl-Mojolicious"

Sat Apr 20 17:13:04 2019 rev:107 rq:695937 version:8.14

Changes:
--------
--- /work/SRC/openSUSE:Factory/perl-Mojolicious/perl-Mojolicious.changes        
2019-02-04 14:25:45.669043835 +0100
+++ 
/work/SRC/openSUSE:Factory/.perl-Mojolicious.new.5536/perl-Mojolicious.changes  
    2019-04-20 17:13:12.510927460 +0200
@@ -1,0 +2,30 @@
+Fri Apr 19 05:17:46 UTC 2019 - Stephan Kulow <co...@suse.com>
+
+- updated to 8.14
+   see /usr/share/doc/packages/perl-Mojolicious/Changes
+
+  8.14  2019-04-18
+    - Added EXPERIMENTAL timer method to Mojo::Promise.
+    - Added header_exists and header_exists_not methods to Test::Mojo.
+    - Fixed a bug where the finally callback in Mojo::Promise was passed a 
value,
+      which is incompatible with the JavaScript API.
+    - Fixed a bug in Mojo::Promise where the finally method could change 
promise
+      values.
+    - Fixed a merge bug in Mojo::Parameters where multiple values sharing the 
same
+      name could get lost.
+
+-------------------------------------------------------------------
+Fri Mar 22 06:19:30 UTC 2019 - Stephan Kulow <co...@suse.com>
+
+- updated to 8.13
+   see /usr/share/doc/packages/perl-Mojolicious/Changes
+
+  8.13  2019-03-21
+    - Added EXPERIMENTAL map method to Mojo::Promise. (jberger)
+    - Added EXPERIMENTAL min_compress_size attribute to Mojolicious::Renderer.
+      (CandyAngel, mjemmeson)
+    - Improved the security of signed cookies by also signing the cookie name.
+      Note that this means that all sessions will be reset.
+    - Fixed Mojo::IOLoop::Server to not check if listen sockets are writable.
+
+-------------------------------------------------------------------

Old:
----
  Mojolicious-8.12.tar.gz

New:
----
  Mojolicious-8.14.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ perl-Mojolicious.spec ++++++
--- /var/tmp/diff_new_pack.RZEvoP/_old  2019-04-20 17:13:14.114929881 +0200
+++ /var/tmp/diff_new_pack.RZEvoP/_new  2019-04-20 17:13:14.114929881 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           perl-Mojolicious
-Version:        8.12
+Version:        8.14
 Release:        0
 %define cpan_name Mojolicious
 Summary:        Real-time web framework

++++++ Mojolicious-8.12.tar.gz -> Mojolicious-8.14.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.12/Changes new/Mojolicious-8.14/Changes
--- old/Mojolicious-8.12/Changes        2019-01-31 00:20:26.000000000 +0100
+++ new/Mojolicious-8.14/Changes        2019-04-18 20:53:24.000000000 +0200
@@ -1,4 +1,22 @@
 
+8.14  2019-04-18
+  - Added EXPERIMENTAL timer method to Mojo::Promise.
+  - Added header_exists and header_exists_not methods to Test::Mojo.
+  - Fixed a bug where the finally callback in Mojo::Promise was passed a value,
+    which is incompatible with the JavaScript API.
+  - Fixed a bug in Mojo::Promise where the finally method could change promise
+    values.
+  - Fixed a merge bug in Mojo::Parameters where multiple values sharing the 
same
+    name could get lost.
+
+8.13  2019-03-21
+  - Added EXPERIMENTAL map method to Mojo::Promise. (jberger)
+  - Added EXPERIMENTAL min_compress_size attribute to Mojolicious::Renderer.
+    (CandyAngel, mjemmeson)
+  - Improved the security of signed cookies by also signing the cookie name.
+    Note that this means that all sessions will be reset.
+  - Fixed Mojo::IOLoop::Server to not check if listen sockets are writable.
+
 8.12  2019-01-27
   - Added EXPERIMENTAL timeout method to Mojo::Promise. (batman)
   - Removed deprecated module Mojolicious::Plugin::PODRenderer.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.12/META.json 
new/Mojolicious-8.14/META.json
--- old/Mojolicious-8.12/META.json      2019-02-01 17:33:33.000000000 +0100
+++ new/Mojolicious-8.14/META.json      2019-04-18 21:10:14.000000000 +0200
@@ -58,6 +58,6 @@
       },
       "x_IRC" : "irc://irc.freenode.net/#mojo"
    },
-   "version" : "8.12",
-   "x_serialization_backend" : "JSON::PP version 4.00"
+   "version" : "8.14",
+   "x_serialization_backend" : "JSON::PP version 4.02"
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.12/META.yml 
new/Mojolicious-8.14/META.yml
--- old/Mojolicious-8.12/META.yml       2019-02-01 17:33:33.000000000 +0100
+++ new/Mojolicious-8.14/META.yml       2019-04-18 21:10:14.000000000 +0200
@@ -31,5 +31,5 @@
   homepage: https://mojolicious.org
   license: http://www.opensource.org/licenses/artistic-license-2.0
   repository: https://github.com/mojolicious/mojo.git
-version: '8.12'
+version: '8.14'
 x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.12/lib/Mojo/Base.pm 
new/Mojolicious-8.14/lib/Mojo/Base.pm
--- old/Mojolicious-8.12/lib/Mojo/Base.pm       2018-12-30 19:18:59.000000000 
+0100
+++ new/Mojolicious-8.14/lib/Mojo/Base.pm       2019-04-12 19:38:24.000000000 
+0200
@@ -242,7 +242,7 @@
   use Role::Tiny;
   sub has { Mojo::Base::attr(__PACKAGE__, @_) }
 
-On Perl 5.20+ you can also append a C<-signatures> flag to all three forms and
+On Perl 5.20+ you can also append a C<-signatures> flag to all four forms and
 enable support for L<subroutine signatures|perlsub/"Signatures">.
 
   # Also enable signatures
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.12/lib/Mojo/IOLoop/Server.pm 
new/Mojolicious-8.14/lib/Mojo/IOLoop/Server.pm
--- old/Mojolicious-8.12/lib/Mojo/IOLoop/Server.pm      2019-01-02 
14:56:13.000000000 +0100
+++ new/Mojolicious-8.14/lib/Mojo/IOLoop/Server.pm      2019-03-19 
18:30:39.000000000 +0100
@@ -91,7 +91,8 @@
   my $self = shift;
   weaken $self;
   ++$self->{active}
-    and $self->reactor->io($self->{handle} => sub { $self->_accept });
+    and $self->reactor->io($self->{handle} => sub { $self->_accept })
+    ->watch($self->{handle}, 1, 0);
 }
 
 sub stop { delete($_[0]{active}) and $_[0]->reactor->remove($_[0]{handle}) }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.12/lib/Mojo/Parameters.pm 
new/Mojolicious-8.14/lib/Mojo/Parameters.pm
--- old/Mojolicious-8.12/lib/Mojo/Parameters.pm 2018-11-22 21:21:52.000000000 
+0100
+++ new/Mojolicious-8.14/lib/Mojo/Parameters.pm 2019-04-02 20:49:20.000000000 
+0200
@@ -53,8 +53,9 @@
 sub merge {
   my $self = shift;
 
-  my @pairs = @_ == 1 ? @{shift->pairs} : @_;
-  while (my ($name, $value) = splice @pairs, 0, 2) {
+  my $merge = @_ == 1 ? shift->to_hash : {@_};
+  for my $name (sort keys %$merge) {
+    my $value = $merge->{$name};
     defined $value ? $self->param($name => $value) : $self->remove($name);
   }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.12/lib/Mojo/Promise.pm 
new/Mojolicious-8.14/lib/Mojo/Promise.pm
--- old/Mojolicious-8.12/lib/Mojo/Promise.pm    2019-01-29 14:41:50.000000000 
+0100
+++ new/Mojolicious-8.14/lib/Mojo/Promise.pm    2019-04-18 20:48:16.000000000 
+0200
@@ -41,6 +41,31 @@
   return $new;
 }
 
+sub map {
+  my ($class, $options) = (shift, ref $_[0] eq 'HASH' ? shift : {});
+  my ($cb, @items) = @_;
+
+  my @start = map { $_->$cb } splice @items, 0,
+    $options->{concurrency} // @items;
+  my $proto = $class->resolve($start[0]);
+
+  my (@trigger, @wait);
+  for my $item (@items) {
+    my $p = $proto->clone;
+    push @trigger, $p;
+    push @wait, $p->then(sub { local $_ = $item; $_->$cb });
+  }
+
+  my @all = map {
+    $proto->clone->resolve($_)->then(
+      sub { shift(@trigger)->resolve if @trigger; @_ },
+      sub { @trigger = (); $proto->clone->reject($_[0]) },
+    )
+  } (@start, @wait);
+
+  return $class->all(@all);
+}
+
 sub race {
   my ($class, @promises) = @_;
   my $new = $promises[0]->clone;
@@ -63,12 +88,8 @@
   return $new;
 }
 
-sub timeout {
-  my ($self, $after, $err)
-    = (ref $_[0] ? shift : shift->new, @_, 'Promise timeout');
-  $self->ioloop->timer($after => sub { $self->reject($err) });
-  return $self;
-}
+sub timer   { shift->_timer('resolve', @_) }
+sub timeout { shift->_timer('reject',  @_) }
 
 sub wait {
   my $self = shift;
@@ -89,19 +110,18 @@
 
 sub _finally {
   my ($new, $finally, $method, @result) = @_;
-  my ($res) = eval { $finally->(@result) };
-  return $new->$method(@result)
-    unless $res && blessed $res && $res->can('then');
-  $res->then(sub { $new->$method(@result) }, sub { $new->$method(@result) });
+  return $new->reject($@) unless eval { $finally->(); 1 };
+  return $new->$method(@result);
 }
 
 sub _settle {
   my ($self, $status) = (shift, shift);
-  $self = $self->new unless ref $self;
+  my $thenable = blessed $_[0] && $_[0]->can('then');
+  $self = $thenable ? $_[0]->clone : $self->new unless ref $self;
 
   $_[0]->then(sub { $self->resolve(@_); () }, sub { $self->reject(@_); () })
     and return $self
-    if blessed $_[0] && $_[0]->can('then');
+    if $thenable;
 
   return $self if $self->{result};
 
@@ -120,6 +140,14 @@
   return $new->resolve(@res);
 }
 
+sub _timer {
+  my ($self, $method, $after, @result) = @_;
+  $self = $self->new unless ref $self;
+  $result[0] = 'Promise timeout' if $method eq 'reject' && !@result;
+  $self->ioloop->timer($after => sub { $self->$method(@result) });
+  return $self;
+}
+
 1;
 
 =encoding utf8
@@ -286,10 +314,36 @@
 
   # Do something on fulfillment and rejection
   $promise->finally(sub {
-    my @value_or_reason = @_;
     say "We are done!";
   });
 
+=head2 map
+
+  my $new = Mojo::Promise->map(sub { ... }, @items);
+  my $new = Mojo::Promise->map({concurrency => 3}, sub { ... }, @items);
+
+Apply a function that returns a L<Mojo::Promise> to each item in a list of
+items while optionally limiting concurrency. Returns a L<Mojo::Promise> that
+collects the results in the same manner as L</all>. If any item's promise is
+rejected, any remaining items which have not yet been mapped will not be. Note
+that this method is EXPERIMENTAL and might change without warning!
+
+  # Perform 3 requests at a time concurrently
+  Mojo::Promise->map({concurrency => 3}, sub { $ua->get_p($_) }, @urls)
+    ->then(sub{ say $_->[0]->res->dom->at('title')->text for @_ });
+
+These options are currently available:
+
+=over 2
+
+=item concurrency
+
+  concurrency => 3
+
+The maximum number of items that are in progress at the same time.
+
+=back
+
 =head2 race
 
   my $new = Mojo::Promise->race(@promises);
@@ -355,6 +409,17 @@
     }
   );
 
+=head2 timer
+
+  my $new  = Mojo::Promise->timer(5 => 'Success!');
+  $promise = $promise->timer(5 => 'Success!');
+  $promise = $promise->timer(5);
+
+Create a new L<Mojo::Promise> object with a timer or attach a timer to an
+existing promise. The promise will be resolved after the given amount of time 
in
+seconds with or without a value. Note that this method is EXPERIMENTAL and 
might
+change without warning!
+
 =head2 timeout
 
   my $new  = Mojo::Promise->timeout(5 => 'Timeout!');
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.12/lib/Mojolicious/Controller.pm 
new/Mojolicious-8.14/lib/Mojolicious/Controller.pm
--- old/Mojolicious-8.12/lib/Mojolicious/Controller.pm  2018-11-22 
21:21:59.000000000 +0100
+++ new/Mojolicious-8.14/lib/Mojolicious/Controller.pm  2019-03-13 
21:34:12.000000000 +0100
@@ -85,7 +85,7 @@
 
       my $valid;
       for my $secret (@$secrets) {
-        my $check = Mojo::Util::hmac_sha1_sum($value, $secret);
+        my $check = Mojo::Util::hmac_sha1_sum("$name=$value", $secret);
         ++$valid and last if Mojo::Util::secure_compare($signature, $check);
       }
       if ($valid) { push @results, $value }
@@ -239,8 +239,8 @@
   return $self->every_signed_cookie($name)->[-1] unless defined $value;
 
   # Response cookie
-  my $checksum = Mojo::Util::hmac_sha1_sum($value, $self->app->secrets->[0]);
-  return $self->cookie($name, "$value--$checksum", $options);
+  my $sum = Mojo::Util::hmac_sha1_sum("$name=$value", 
$self->app->secrets->[0]);
+  return $self->cookie($name, "$value--$sum", $options);
 }
 
 sub stash { Mojo::Util::_stash(stash => @_) }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Mojolicious-8.12/lib/Mojolicious/Guides/Contributing.pod 
new/Mojolicious-8.14/lib/Mojolicious/Guides/Contributing.pod
--- old/Mojolicious-8.12/lib/Mojolicious/Guides/Contributing.pod        
2018-12-31 13:37:21.000000000 +0100
+++ new/Mojolicious-8.14/lib/Mojolicious/Guides/Contributing.pod        
2019-04-12 19:39:32.000000000 +0200
@@ -182,22 +182,6 @@
 
 =back
 
-=head1 DONATIONS
-
-L<Mojolicious> is open source and free to use. However, the amount of effort
-needed to maintain the project and develop new features for it is not
-sustainable without proper financial backing. You can support the ongoing
-development of L<Mojolicious> through PayPal (C<donati...@mojolicious.org>).
-
-If you run a business and use L<Mojolicious> in a revenue generating product, 
it
-makes business sense to support L<Mojolicious> development. Because it ensures
-that the project your product relies on stays healthy and actively maintained.
-It can also help your exposure within the community and will make it easier to
-attract L<Mojolicious> developers.
-
-Please email us (C<donati...@mojolicious.org>) if you have any questions about
-becoming a sponsor.
-
 =head1 CODE OF CONDUCT
 
 Like the technical community as a whole, the L<Mojolicious> team and community
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.12/lib/Mojolicious/Guides/Routing.pod 
new/Mojolicious-8.14/lib/Mojolicious/Guides/Routing.pod
--- old/Mojolicious-8.12/lib/Mojolicious/Guides/Routing.pod     2019-01-05 
02:32:59.000000000 +0100
+++ new/Mojolicious-8.14/lib/Mojolicious/Guides/Routing.pod     2019-04-05 
00:21:34.000000000 +0200
@@ -855,7 +855,7 @@
     my $resource = $r->any("/$name")->to("$name#");
 
     # Render a list of resources
-    $resource->get->to('#index')->name($name);
+    $resource->get('/')->to('#index')->name($name);
 
     # Render a form to create a new resource (submitted to "store")
     $resource->get('/create')->to('#create')->name("create_$name");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.12/lib/Mojolicious/Renderer.pm 
new/Mojolicious-8.14/lib/Mojolicious/Renderer.pm
--- old/Mojolicious-8.12/lib/Mojolicious/Renderer.pm    2018-11-22 
21:21:59.000000000 +0100
+++ new/Mojolicious-8.14/lib/Mojolicious/Renderer.pm    2019-03-13 
23:50:43.000000000 +0100
@@ -14,7 +14,8 @@
 has default_format => 'html';
 has encoding       => 'UTF-8';
 has [qw(handlers helpers)] => sub { {} };
-has paths => sub { [] };
+has min_compress_size => 860;
+has paths             => sub { [] };
 
 # Bundled templates
 my $TEMPLATES = path(__FILE__)->sibling('resources', 'templates');
@@ -122,7 +123,7 @@
 
   # Gzip compression
   my $res = $c->res;
-  if ($self->compress) {
+  if ($self->compress && length($output) >= $self->min_compress_size) {
     my $headers = $res->headers;
     $headers->append(Vary => 'Accept-Encoding');
     my $gzip = ($c->req->headers->accept_encoding // '') =~ /gzip/i;
@@ -328,6 +329,15 @@
 
 Registered helpers.
 
+=head2 min_compress_size
+
+  my $size  = $renderer->min_compress_size;
+  $renderer = $renderer->min_compress_size(1024);
+
+Minimum output size in bytes required for compression to be used if enabled,
+defaults to C<860>. Note that this attribute is EXPERIMENTAL and might change
+without warning!
+
 =head2 paths
 
   my $paths = $renderer->paths;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.12/lib/Mojolicious.pm 
new/Mojolicious-8.14/lib/Mojolicious.pm
--- old/Mojolicious-8.12/lib/Mojolicious.pm     2019-01-02 19:04:39.000000000 
+0100
+++ new/Mojolicious-8.14/lib/Mojolicious.pm     2019-03-21 23:06:06.000000000 
+0100
@@ -59,7 +59,7 @@
 has validator => sub { Mojolicious::Validator->new };
 
 our $CODENAME = 'Supervillain';
-our $VERSION  = '8.12';
+our $VERSION  = '8.14';
 
 sub BUILD_DYNAMIC {
   my ($class, $method, $dyn_methods) = @_;
@@ -1078,6 +1078,8 @@
 
 Michael Harris
 
+Michael Jemmeson
+
 Mike Magowan
 
 Mirko Westermeier
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.12/lib/Test/Mojo.pm 
new/Mojolicious-8.14/lib/Test/Mojo.pm
--- old/Mojolicious-8.12/lib/Test/Mojo.pm       2018-11-22 21:21:40.000000000 
+0100
+++ new/Mojolicious-8.14/lib/Test/Mojo.pm       2019-03-23 02:23:14.000000000 
+0100
@@ -121,6 +121,20 @@
 sub get_ok  { shift->_build_ok(GET  => @_) }
 sub head_ok { shift->_build_ok(HEAD => @_) }
 
+sub header_exists {
+  my ($self, $name, $desc) = @_;
+  $desc = _desc($desc, qq{header "$name" exists});
+  return $self->_test('ok', !!@{$self->tx->res->headers->every_header($name)},
+    $desc);
+}
+
+sub header_exists_not {
+  my ($self, $name, $desc) = @_;
+  $desc = _desc($desc, qq{no "$name" header});
+  return $self->_test('ok', !@{$self->tx->res->headers->every_header($name)},
+    $desc);
+}
+
 sub header_is {
   my ($self, $name, $value, $desc) = @_;
   $desc = _desc($desc, "$name: " . ($value // ''));
@@ -724,6 +738,20 @@
 Perform a C<HEAD> request and check for transport errors, takes the same
 arguments as L<Mojo::UserAgent/"head">, except for the callback.
 
+=head2 header_exists
+
+  $t = $t->header_exists('ETag');
+  $t = $t->header_exists('ETag', 'header exists');
+
+Check if response header exists.
+
+=head2 header_exists_not
+
+  $t = $t->header_exists_not('ETag');
+  $t = $t->header_exists_not('ETag', 'header is missing');
+
+Opposite of L</"header_exists">.
+
 =head2 header_is
 
   $t = $t->header_is(ETag => '"abc321"');
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.12/t/mojo/parameters.t 
new/Mojolicious-8.14/t/mojo/parameters.t
--- old/Mojolicious-8.12/t/mojo/parameters.t    2018-11-22 21:22:59.000000000 
+0100
+++ new/Mojolicious-8.14/t/mojo/parameters.t    2019-04-02 20:54:59.000000000 
+0200
@@ -37,6 +37,17 @@
 is $params->merge(Mojo::Parameters->new(z => 6))->to_string,
   'foo=b%3Bar&a=4&a=5&b=6&b=7&c=f%3Boo&x=1&y=3&z=6', 'right format';
 
+# Merge (instances)
+$params
+  = Mojo::Parameters->new->merge(Mojo::Parameters->new(foo => [123, 456]));
+is_deeply $params->to_hash, {foo => [123, 456]}, 'right structure';
+$params = Mojo::Parameters->new(foo => 321)
+  ->merge(Mojo::Parameters->new(foo => [123, 456]));
+is_deeply $params->to_hash, {foo => [123, 456]}, 'right structure';
+$params = Mojo::Parameters->new(bar => 321)
+  ->merge(Mojo::Parameters->new(foo => [123, 456]));
+is_deeply $params->to_hash, {foo => [123, 456], bar => 321}, 'right structure';
+
 # Param
 $params
   = Mojo::Parameters->new('foo=b%3Bar&a=4&a=5&b=6&b=7&c=f%3Boo&x=1&y=3&z=6');
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.12/t/mojo/promise.t 
new/Mojolicious-8.14/t/mojo/promise.t
--- old/Mojolicious-8.12/t/mojo/promise.t       2019-01-29 14:40:35.000000000 
+0100
+++ new/Mojolicious-8.14/t/mojo/promise.t       2019-04-18 20:51:27.000000000 
+0200
@@ -31,11 +31,11 @@
 # Resolved with finally
 $promise = Mojo::Promise->new;
 @results = ();
-$promise->finally(sub { @results = @_; 'fail' })
+$promise->finally(sub { @results = ('finally'); 'fail' })
   ->then(sub { push @results, @_ });
 $promise->resolve('hello', 'world');
 Mojo::IOLoop->one_tick;
-is_deeply \@results, ['hello', 'world', 'hello', 'world'], 'promise settled';
+is_deeply \@results, ['finally', 'hello', 'world'], 'promise settled';
 
 # Rejected
 $promise = Mojo::Promise->new;
@@ -62,11 +62,11 @@
 # Rejected with finally
 $promise = Mojo::Promise->new;
 @errors  = ();
-$promise->finally(sub { @errors = @_; 'fail' })
+$promise->finally(sub { @errors = ('finally'); 'fail' })
   ->then(undef, sub { push @errors, @_ });
 $promise->reject('bye', 'world');
 Mojo::IOLoop->one_tick;
-is_deeply \@errors, ['bye', 'world', 'bye', 'world'], 'promise settled';
+is_deeply \@errors, ['finally', 'bye', 'world'], 'promise settled';
 
 # No state change
 $promise = Mojo::Promise->new;
@@ -120,17 +120,31 @@
 Mojo::IOLoop->one_tick;
 is_deeply \@errors, ['hello world'], 'promise rejected';
 
+# Double finally
+$promise = Mojo::Promise->new;
+@results = ();
+$promise->finally(sub { push @results, 'finally1' })
+  ->finally(sub { push @results, 'finally2' });
+$promise->resolve('pass');
+Mojo::IOLoop->one_tick;
+is_deeply \@results, ['finally1', 'finally2'], 'promise not resolved';
+
 # Resolved nested with finally
 $promise  = Mojo::Promise->new;
 $promise2 = Mojo::Promise->new;
 @results  = ();
-$promise->finally(sub {$promise2})->finally(sub { @results = @_ });
+$promise->finally(sub {$promise2})->finally(sub { @results = ('finally') });
 $promise->resolve('pass');
 Mojo::IOLoop->one_tick;
-is_deeply \@results, [], 'promise not resolved';
-$promise2->resolve('fail');
+is_deeply \@results, ['finally'], 'promise already resolved';
+
+# Exception in finally
+$promise = Mojo::Promise->new;
+@results = ();
+$promise->finally(sub { die "Test!\n" })->catch(sub { push @results, @_ });
+$promise->resolve('pass');
 Mojo::IOLoop->one_tick;
-is_deeply \@results, ['pass'], 'promise resolved';
+is_deeply \@results, ["Test!\n"], 'promise rejected';
 
 # Clone
 my $loop = Mojo::IOLoop->new;
@@ -196,6 +210,17 @@
 Mojo::Promise->timeout(0.025)->catch(sub { @errors = @_ })->wait;
 is_deeply \@errors, ['Promise timeout'], 'default timeout message';
 
+# Timer without value
+@results = ();
+Mojo::Promise->timer(0.025)->then(sub { @results = (@_, 'works!') })->wait;
+is_deeply \@results, ['works!'], 'default timer result';
+
+# Timer with values
+@results = ();
+Mojo::Promise->new->timer(0, 'first', 'second')
+  ->then(sub { @results = (@_, 'works too!') })->wait;
+is_deeply \@results, ['first', 'second', 'works too!'], 'timer result';
+
 # All
 $promise  = Mojo::Promise->new->then(sub {@_});
 $promise2 = Mojo::Promise->new->then(sub {@_});
@@ -239,4 +264,58 @@
 is_deeply \@errors, ['first', 'works too', 'second', 'works too'],
   'promises rejected';
 
+# Map
+my @started;
+(@results, @errors) = ();
+$promise = Mojo::Promise->map(sub { push @started, $_; $_ }, 1 .. 5)
+  ->then(sub { @results = @_ }, sub { @errors = @_ });
+is_deeply \@started, [1, 2, 3, 4, 5], 'all started without concurrency';
+$promise->wait;
+is_deeply \@results, [[1], [2], [3], [4], [5]], 'correct result';
+is_deeply \@errors, [], 'promise not rejected';
+
+# Map (with concurrency limit)
+my $concurrent = 0;
+(@results, @errors) = ();
+Mojo::Promise->map(
+  {concurrency => 3},
+  sub {
+    my $n = $_;
+    fail 'Concurrency too high' if ++$concurrent > 3;
+    Mojo::Promise->resolve->then(sub {
+      fail 'Concurrency too high' if $concurrent-- > 3;
+      $n;
+    });
+  },
+  1 .. 5
+)->then(sub { @results = @_ }, sub { @errors = @_ })->wait;
+is_deeply \@results, [[1], [2], [3], [4], [5]], 'correct result';
+is_deeply \@errors, [], 'promise not rejected';
+
+# Map (with reject)
+(@started, @results, @errors) = ();
+Mojo::Promise->map(
+  {concurrency => 3},
+  sub {
+    my $n = $_;
+    push @started, $n;
+    Mojo::Promise->resolve->then(sub { Mojo::Promise->reject($n) });
+  },
+  1 .. 5
+)->then(sub { @results = @_ }, sub { @errors = @_ })->wait;
+is_deeply \@results, [], 'promise not resolved';
+is_deeply \@errors, [1], 'correct errors';
+is_deeply \@started, [1, 2, 3], 'only initial batch started';
+
+# Map (custom event loop)
+my $ok;
+$loop = Mojo::IOLoop->new;
+$promise
+  = Mojo::Promise->map(sub { Mojo::Promise->new(ioloop => $loop)->resolve }, 
1);
+is $promise->ioloop, $loop, 'same loop';
+isnt $promise->ioloop, Mojo::IOLoop->singleton, 'not the singleton';
+$promise->then(sub { $ok = 1; $loop->stop });
+$loop->start;
+ok $ok, 'loop completed';
+
 done_testing();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.12/t/mojo/template.t 
new/Mojolicious-8.14/t/mojo/template.t
--- old/Mojolicious-8.12/t/mojo/template.t      2018-11-22 21:23:08.000000000 
+0100
+++ new/Mojolicious-8.14/t/mojo/template.t      2019-03-19 21:38:55.000000000 
+0100
@@ -39,6 +39,11 @@
 $output = $mt->render('<%= (1,2,3)[1] %><%== (1,2,3)[2] %>');
 is $output, "23\n", 'no ambiguity';
 
+# String
+$mt     = Mojo::Template->new;
+$output = $mt->render('Just a <%= "test" %>');
+is $output, "Just a test\n", 'rendered string';
+
 # Trim tag
 $mt     = Mojo::Template->new;
 $output = $mt->render(" ♥    <%= 'test♥' =%> \n");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.12/t/mojolicious/lite_app.t 
new/Mojolicious-8.14/t/mojolicious/lite_app.t
--- old/Mojolicious-8.12/t/mojolicious/lite_app.t       2018-11-22 
21:23:19.000000000 +0100
+++ new/Mojolicious-8.14/t/mojolicious/lite_app.t       2019-03-23 
02:24:28.000000000 +0100
@@ -726,7 +726,10 @@
   ->header_is(Server => 'Mojolicious (Perl)')->content_is('root fallback!');
 
 # Root with format
-$t->get_ok('/.html')->status_is(200)->header_is(Server => 'Mojolicious (Perl)')
+$t->get_ok('/.html')->status_is(200)->header_exists_not('Servers')
+  ->header_exists_not('Servers', 'the header is missing')
+  ->header_exists('Server')->header_exists('Server', 'the header exists')
+  ->header_is(Server => 'Mojolicious (Perl)')
   ->content_is("/root.html\n/root.html\n/root.html\n/root.html\n/root.html\n");
 
 # Reverse proxy with "X-Forwarded-For"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Mojolicious-8.12/t/mojolicious/renderer.t 
new/Mojolicious-8.14/t/mojolicious/renderer.t
--- old/Mojolicious-8.12/t/mojolicious/renderer.t       2018-11-22 
21:23:12.000000000 +0100
+++ new/Mojolicious-8.14/t/mojolicious/renderer.t       2019-03-13 
01:05:14.000000000 +0100
@@ -143,6 +143,17 @@
   'right "Content-Encoding" value';
 is $c->res->body, $output, 'same string';
 
+# Compression (below minimum length)
+$output = 'a' x 850;
+$c      = $app->build_controller;
+$c->req->headers->accept_encoding('gzip');
+$renderer->respond($c, $output, 'html');
+is $c->res->headers->content_type, 'text/html;charset=UTF-8',
+  'right "Content-Type" value';
+ok !$c->res->headers->vary,             'no "Vary" value';
+ok !$c->res->headers->content_encoding, 'no "Content-Encoding" value';
+is $c->res->body, $output, 'same string';
+
 # Missing method (AUTOLOAD)
 my $class = ref $first->myapp;
 eval { $first->myapp->missing };


Reply via email to