Acme-CPANModulesBundle-Import-MojoliciousAdvent-2018

 view release on metacpan or  search on metacpan

devdata/https_mojolicious.io_blog_2018_12_03_higher-order-promises_  view on Meta::CPAN

    );
</code></pre>

<h3>Any</h3>

<p>An &quot;any&quot; Promise resolves immediately when the first of its Promises resolves. This is slightly different from <code>race</code> because at least one Promise must resolve. A Promise being rejected doesn&#39;t resolve the <code>any</code>...

<p>Here&#39;s a program that extracts the configured CPAN mirrors and tests that it can get the <em>index.html</em> file. To ensure that it finds that file and not some captive portal, it looks for &quot;Jarkko&quot; in the body:</p>

<pre><code>use v5.28;
use utf8;
use strict;
use warnings;
use feature qw(signatures);
no warnings qw(experimental::signatures);

use File::Spec::Functions;
use Mojo::Promise;
use Mojo::Promise::Role::HigherOrder;
use Mojo::UserAgent;
use Mojo::URL;

devdata/https_mojolicious.io_blog_2018_12_03_higher-order-promises_  view on Meta::CPAN

$any_promise-&gt;wait;
</code></pre>

<h3>Some</h3>

<p>A <code>some</code> Promise resolves when a certain number of its Promises resolve. You specify how many you need to succeed and the the <code>some</code> Promise resolves when that number resolve. This should act like <code>some</code> in <a href...

<p>This example modifies the previous program to find more than one mirror that works. You can specify the number that need to work for the <code>some</code> to resolve:</p>

<pre><code>use v5.28;
use utf8;
use strict;
use warnings;
use feature qw(signatures);
no warnings qw(experimental::signatures);

use File::Spec::Functions;
use Mojo::Promise;
use Mojo::Promise::Role::HigherOrder;
use Mojo::UserAgent;
use Mojo::URL;

devdata/https_mojolicious.io_blog_2018_12_03_higher-order-promises_  view on Meta::CPAN

$some_promise-&gt;wait;
</code></pre>

<h3>None</h3>

<p>A &quot;none&quot; Promise resolves when all of the its Promises are rejected. It&#39;s a trivial case that might be useful somewhere and I created it mostly because Perl 6 has a <a href="https://docs.perl6.org/routine/none">none Junction</a> (whi...

<p>For this very simple example, consider the task to check that no sites are that annoying &quot;404 File Not Found&quot;:</p>

<pre><code>use v5.28;
use utf8;
use strict;
use warnings;
use feature qw(signatures);
no warnings qw(experimental::signatures);

use Mojo::UserAgent;
my $ua = Mojo::UserAgent-&gt;new;

use Mojo::Promise;
use Mojo::Promise::Role::HigherOrder;

devdata/https_mojolicious.io_blog_2018_12_05_compound-selectors_  view on Meta::CPAN


<p>However, this article isn&#39;t about all the fancy things that you can do with selectors. You know that they exist and you can see the possibilities in <a href="https://mojolicious.org/perldoc/Mojo/DOM/CSS">Mojo::CSS::Selectors</a>. I&#39;ll show...

<h2>Using Selectors with Mojo</h2>

<p>But you can do much more with these. With <a href="https://mojolicious.org/perldoc/Mojo/DOM">Mojo::DOM</a>, which supports CSS Selectors <a href="https://www.w3.org/TR/2018/PR-selectors-3-20180911/">Level 3</a> (and some stuff from <a href="https:...

<p>Start with some HTML. Note the fancy new <a href="https://www.effectiveperlprogramming.com/2016/12/strip-leading-spaces-from-here-docs-with-v5-26/">indented here doc syntax introduced in Perl 5.26</a>:</p>

<pre><code>use v5.28;
use utf8;
use strict;
use warnings;

use Mojo::DOM;

my $selector = $ARGV[0] // &#39;img&#39;;

my $html =&lt;&lt;~&#39;HTML&#39;;

    &lt;img id=&quot;farnworth &quot; class=&quot;human&quot; src=&quot;...&quot; /&gt;

devdata/https_mojolicious.io_blog_2018_12_05_compound-selectors_  view on Meta::CPAN


<h2>How about those new emojis?</h2>

<p>While writing about the <a href="https://www.effectiveperlprogramming.com/2018/08/find-the-new-emojis-in-perls-unicode-support/">Unicode 9 updates in Perl v5.26</a>, I wondered what I could show that might be interesting. How about figuring out wh...

<p>My first attempt simply trawled through every character and compared the various Unicode properties to see which code numbers changed from <code>Unassigned</code> to <code>Present_In</code>. That was fine, but then I found that someone was already...

<p>I won&#39;t explain everything in this program. Trust me that it uses <a href="https://mojolicious.org/perldoc/Mojo/UserAgent">Mojo::UserAgent</a> to fetch the data, extracts the DOM, and finds the text I want by using the compound selector <code>...

<pre><code>use v5.28;
use utf8;
use strict;
use warnings;
use open qw(:std :utf8);
use charnames qw();

use Mojo::UserAgent;
my $ua = Mojo::UserAgent-&gt;new;

my $url = &#39;https://blog.emojipedia.org/new-unicode-9-emojis/&#39;;
my $tx = $ua-&gt;get( $url );

die &quot;That didn&#39;t work!\n&quot; if $tx-&gt;error;

devdata/https_mojolicious.io_blog_2018_12_05_compound-selectors_  view on Meta::CPAN


<p>I used the same program to find <a href="https://www.effectiveperlprogramming.com/2018/08/use-unicode-10-in-perl-v5-28/">the Unicode 10 updates in v5.28</a> too.</p>

<h2>Extracting columns from a table</h2>

<p>Not impressed yet? How about slicing a table with CSS Selectors? Here&#39;s a short table that has ID, name, and score columns. I want to sum all of the scores.</p>

<p>I&#39;m not afraid of doing with this with regexes (emphasize plural there!) but it&#39;s easier with <a href="https://mojolicious.org/perldoc/Mojo/DOM">Mojo::DOM</a>. The compound selector finds the table by its class, selects each row, and addre...

<pre><code>use v5.26;
use utf8;
use strict;
use warnings;

use List::Util qw(sum);
use Mojo::DOM;

my $html = &lt;&lt;~&#39;HTML&#39;;
    &lt;table class=&quot;scores&quot;&gt;
    &lt;tr&gt;&lt;th&gt;ID&lt;/th&gt;&lt;th&gt;Name&lt;/th&gt;&lt;th&gt;Score&lt;/th&gt;&lt;/tr&gt;

devdata/https_mojolicious.io_blog_2018_12_20_testing-dancer_  view on Meta::CPAN

I&#39;ll break the test script down a bit but if you want to see any of these files look at the <a href="https://github.com/MojoliciousDotIO/mojolicious.io/tree/master/blog/2018/12/20/testing-dancer/ex">blog repo</a> for a full listing.
Instead, let&#39;s load this into a test script.</p>

<pre><code>use Mojo::Base -strict;
</code></pre>

<p>Now if you aren&#39;t familiar, <code>use Mojo::Base -strict</code> is a quick way to say</p>

<pre><code>use strict;
use warnings;
use utf8;
use IO::Handle;
use feature &#39;:5.10&#39;;
</code></pre>

<p>but saves a lot of typing.
Next we load the necessary testing libraries.
Then make an instance of <code>Test::Mojo</code> composed with the <code>PSGI</code> role and make a new instance that points to the app we want to test.</p>

<pre><code>use Test::More;
use Test::Mojo;

devdata/https_mojolicious.io_blog_2018_12_20_testing-dancer_  view on Meta::CPAN

  -&gt;content_type_like(qr[text/plain])
  -&gt;content_is(&#39;hello world&#39;);
</code></pre>

<p>Each of the above method calls is a test.
The first, <code>get_ok</code>, builds a transaction and requests the resource.
Since the url is relative, it is handled by the app (if we wanted we could request and web resource too using a fully qualified url).
The transaction is stored in the tester object (<code>$t</code>) and all following tests will check it until it is replaced by the next request.</p>

<p>The remaining tests are reasonably self-explanatory, we check that the response status was 200, that we got a content type header that we expected and that its content is as we expect.
The content has already been utf-8 decoded, and the script has implicitly <code>use utf8</code>, so if you expected unicode, you can compare them easily.
The tests return the tester object so chaining is possible, making for visually clean sets of tests.</p>

<p>The next test is similar but this one uses the standard <a href="https://mojolicious.org/perldoc/Mojo/UserAgent">Mojo::UserAgent</a> style request generation to build a query string naming Santa for our greeting.
The tests are all the same except of course that it checks that the content greets Santa.</p>

<pre><code>$t-&gt;get_ok(&#39;/text&#39;, form =&gt; { name =&gt; &#39;santa&#39; })
  -&gt;status_is(200)
  -&gt;content_type_like(qr[text/plain])
  -&gt;content_is(&#39;hello santa&#39;);
</code></pre>



( run in 1.054 second using v1.01-cache-2.11-cpan-49f99fa48dc )