The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Build.PL 712
Changes 029
LICENSE 11
MANIFEST 110
META.yml 69
Makefile.PL 814
README 939
dist.ini 16
examples/author-country.pl 03
examples/author.pl 05
examples/complex-either-and.pl 34
examples/complex-either-not.pl 15
examples/complex-nested-either-and.pl 026
examples/complex.pl 03
examples/distribution.pl 03
examples/module.pl 023
examples/pod.pl 011
examples/recent.pl 022
examples/recent_today.pl 019
examples/rev_deps-recursive.pl 69
examples/rev_deps.pl 817
examples/totals.pl 017
lib/MetaCPAN/Client/Author.pm 65
lib/MetaCPAN/Client/Distribution.pm 24
lib/MetaCPAN/Client/Favorite.pm 24
lib/MetaCPAN/Client/File.pm 24
lib/MetaCPAN/Client/Module.pm 24
lib/MetaCPAN/Client/Pod.pm 0108
lib/MetaCPAN/Client/Rating.pm 24
lib/MetaCPAN/Client/Release.pm 2327
lib/MetaCPAN/Client/Request.pm 626
lib/MetaCPAN/Client/ResultSet.pm 2663
lib/MetaCPAN/Client/Role/Entity.pm 317
lib/MetaCPAN/Client.pm 23143
t/00-compile.t 23
t/api/pod.t 016
t/request.t 15
t/resultset.t 17
t/ua_trap.t 051
39 files changed (This is a version diff) 152778
@@ -1,18 +1,18 @@
 
-# This file was automatically generated by Dist::Zilla::Plugin::ModuleBuild v5.015.
+# This file was automatically generated by Dist::Zilla::Plugin::ModuleBuild v5.020.
 use strict;
 use warnings;
 
-use Module::Build 0.3601;
+use Module::Build 0.28;
 
 
 my %module_build_args = (
   "build_requires" => {
-    "Module::Build" => "0.3601"
+    "Module::Build" => "0.28"
   },
   "configure_requires" => {
-    "ExtUtils::MakeMaker" => "6.30",
-    "Module::Build" => "0.3601"
+    "ExtUtils::MakeMaker" => 0,
+    "Module::Build" => "0.28"
   },
   "dist_abstract" => "A comprehensive, DWIM-featured client to the MetaCPAN API",
   "dist_author" => [
@@ -20,7 +20,7 @@ my %module_build_args = (
     "Mickey Nasriachi <mickey\@cpan.org>"
   ],
   "dist_name" => "MetaCPAN-Client",
-  "dist_version" => "1.003000",
+  "dist_version" => "1.008000",
   "license" => "perl",
   "module_name" => "MetaCPAN::Client",
   "recommends" => {},
@@ -31,6 +31,7 @@ my %module_build_args = (
     "JSON::MaybeXS" => 0,
     "Moo" => 0,
     "Moo::Role" => 0,
+    "Safe::Isa" => 0,
     "Search::Elasticsearch" => "1.10",
     "Search::Elasticsearch::Scroll" => 0,
     "Try::Tiny" => 0,
@@ -44,6 +45,8 @@ my %module_build_args = (
     "IPC::Open3" => 0,
     "Test::Fatal" => 0,
     "Test::More" => 0,
+    "Test::Requires" => 0,
+    "base" => 0,
     "perl" => "5.006"
   }
 );
@@ -53,9 +56,11 @@ my %fallback_build_requires = (
   "File::Spec" => 0,
   "IO::Handle" => 0,
   "IPC::Open3" => 0,
-  "Module::Build" => "0.3601",
+  "Module::Build" => "0.28",
   "Test::Fatal" => 0,
   "Test::More" => 0,
+  "Test::Requires" => 0,
+  "base" => 0,
   "perl" => "5.006"
 );
 
@@ -1,5 +1,34 @@
 Revision history for MetaCPAN-Client (previously MetaCPAN-API)
 
+1.008000    22.11.14
+            * RT #99498: added API for 'match_all' queries via all($type) (oalders, mickeyn)
+            * GH #21: make 'domain' and 'version' settable via new() (oalders)
+            * RT #94491: document nested queries (neilb, mickeyn)
+
+1.007001    09.10.14
+            * GH #18: HTTP::Tiny::Mech and WWW::Mechanize::Cached downgraded to being non-essential for tests (kentnl)
+            * GH #19: Include 'metadata' in known_fields for ::Release (kentnl)
+
+1.007000    14.08.14
+            * Ensure passing user specified ua values to all parts internally,
+              including to Elasticsearch (kentnl) GH #17 RT#95796
+            * Entity consuming roles now have a 'client' attribute which will lazy build,
+              or reference the MetaCPAN::Client that created them via new_from_request (kentnl) GH #17
+
+1.006000    24.06.14
+            * Add 'recent' functionality (latest releases)
+
+1.005000    09.06.14
+            * Add Pod object to allow direct POD fetching (reneeb)
+            * Support single element without wrapping arrayref in structures
+            * Updated documents - basic/complex search links and wording (tsibley)
+
+1.004001    27.05.14
+            * correct rev_deps query
+
+1.004000    27.05.14
+            * reworked ResultSet to allow RS in non-scrolled searches.
+
 1.003000    05.05.14
             * Add proper POD fetching from module/file objects.
             * GH #1: Switch from JSON.pm to JSON::MaybeXS.
@@ -22,7 +22,7 @@ This is free software, licensed under:
                      Version 1, February 1989
 
  Copyright (C) 1989 Free Software Foundation, Inc.
- 51 Franklin St, Suite 500, Boston, MA  02110-1335  USA
+ 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
  Everyone is permitted to copy and distribute verbatim copies
  of this license document, but changing it is not allowed.
@@ -1,4 +1,4 @@
-# This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.015.
+# This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.020.
 Build.PL
 Changes
 LICENSE
@@ -12,17 +12,24 @@ examples/author.pl
 examples/author_releases.pl
 examples/complex-either-and.pl
 examples/complex-either-not.pl
+examples/complex-nested-either-and.pl
 examples/complex.pl
 examples/distribution.pl
+examples/module.pl
+examples/pod.pl
+examples/recent.pl
+examples/recent_today.pl
 examples/release.pl
 examples/rev_deps-recursive.pl
 examples/rev_deps.pl
+examples/totals.pl
 lib/MetaCPAN/Client.pm
 lib/MetaCPAN/Client/Author.pm
 lib/MetaCPAN/Client/Distribution.pm
 lib/MetaCPAN/Client/Favorite.pm
 lib/MetaCPAN/Client/File.pm
 lib/MetaCPAN/Client/Module.pm
+lib/MetaCPAN/Client/Pod.pm
 lib/MetaCPAN/Client/Rating.pm
 lib/MetaCPAN/Client/Release.pm
 lib/MetaCPAN/Client/Request.pm
@@ -37,6 +44,7 @@ t/api/distribution.t
 t/api/favorite.t
 t/api/file.t
 t/api/module.t
+t/api/pod.t
 t/api/rating.t
 t/api/release.t
 t/author-critic.t
@@ -46,3 +54,4 @@ t/release-pod-coverage.t
 t/release-pod-syntax.t
 t/request.t
 t/resultset.t
+t/ua_trap.t
@@ -7,15 +7,17 @@ build_requires:
   File::Spec: 0
   IO::Handle: 0
   IPC::Open3: 0
-  Module::Build: 0.3601
+  Module::Build: 0.28
   Test::Fatal: 0
   Test::More: 0
+  Test::Requires: 0
+  base: 0
   perl: 5.006
 configure_requires:
-  ExtUtils::MakeMaker: 6.30
-  Module::Build: 0.3601
+  ExtUtils::MakeMaker: 0
+  Module::Build: 0.28
 dynamic_config: 0
-generated_by: 'Dist::Zilla version 5.015, CPAN::Meta::Converter version 2.120921'
+generated_by: 'Dist::Zilla version 5.020, CPAN::Meta::Converter version 2.142060'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -30,11 +32,12 @@ requires:
   JSON::MaybeXS: 0
   Moo: 0
   Moo::Role: 0
+  Safe::Isa: 0
   Search::Elasticsearch: 1.10
   Search::Elasticsearch::Scroll: 0
   Try::Tiny: 0
   strict: 0
   warnings: 0
 resources:
-  repository: git://github.com/CPAN-API/metacpan-client.git
-version: 1.003000
+  repository: https://github.com/CPAN-API/metacpan-client.git
+version: 1.008000
@@ -1,11 +1,11 @@
 
-# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.015.
+# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.020.
 use strict;
 use warnings;
 
 
 
-use ExtUtils::MakeMaker 6.30;
+use ExtUtils::MakeMaker ;
 
 
 
@@ -13,11 +13,11 @@ my %WriteMakefileArgs = (
   "ABSTRACT" => "A comprehensive, DWIM-featured client to the MetaCPAN API",
   "AUTHOR" => "Sawyer X <xsawyerx\@cpan.org>, Mickey Nasriachi <mickey\@cpan.org>",
   "BUILD_REQUIRES" => {
-    "Module::Build" => "0.3601"
+    "Module::Build" => "0.28"
   },
   "CONFIGURE_REQUIRES" => {
-    "ExtUtils::MakeMaker" => "6.30",
-    "Module::Build" => "0.3601"
+    "ExtUtils::MakeMaker" => 0,
+    "Module::Build" => "0.28"
   },
   "DISTNAME" => "MetaCPAN-Client",
   "EXE_FILES" => [],
@@ -29,6 +29,7 @@ my %WriteMakefileArgs = (
     "JSON::MaybeXS" => 0,
     "Moo" => 0,
     "Moo::Role" => 0,
+    "Safe::Isa" => 0,
     "Search::Elasticsearch" => "1.10",
     "Search::Elasticsearch::Scroll" => 0,
     "Try::Tiny" => 0,
@@ -40,9 +41,11 @@ my %WriteMakefileArgs = (
     "IO::Handle" => 0,
     "IPC::Open3" => 0,
     "Test::Fatal" => 0,
-    "Test::More" => 0
+    "Test::More" => 0,
+    "Test::Requires" => 0,
+    "base" => 0
   },
-  "VERSION" => "1.003000",
+  "VERSION" => "1.008000",
   "test" => {
     "TESTS" => "t/*.t t/api/*.t"
   }
@@ -56,14 +59,17 @@ my %FallbackPrereqs = (
   "IO::Handle" => 0,
   "IPC::Open3" => 0,
   "JSON::MaybeXS" => 0,
-  "Module::Build" => "0.3601",
+  "Module::Build" => "0.28",
   "Moo" => 0,
   "Moo::Role" => 0,
+  "Safe::Isa" => 0,
   "Search::Elasticsearch" => "1.10",
   "Search::Elasticsearch::Scroll" => 0,
   "Test::Fatal" => 0,
   "Test::More" => 0,
+  "Test::Requires" => 0,
   "Try::Tiny" => 0,
+  "base" => 0,
   "strict" => 0,
   "warnings" => 0
 );
@@ -3,13 +3,13 @@ NAME
     API
 
 VERSION
-    version 1.003000
+    version 1.008000
 
 SYNOPSIS
         # simple usage
         my $mcpan  = MetaCPAN::Client->new();
         my $author = $mcpan->author('XSAWYERX');
-        my $dist   = $mcpan->distribuion('MetaCPAN-Client');
+        my $dist   = $mcpan->distribution('MetaCPAN-Client');
 
         # advanced usage with cache (contributed by Kent Fredric)
         use CHI;
@@ -76,8 +76,8 @@ METHODS
     search.
 
   distribution
-        my $dist = $mcpan->dist('MetaCPAN-Client');
-        my $dist = $mcpan->dist($search_spec);
+        my $dist = $mcpan->distribution('MetaCPAN-Client');
+        my $dist = $mcpan->distribution($search_spec);
 
     Finds a distribution by either its distribution name or by a search spec
     defined by a hash reference. Since it is common to many other searches,
@@ -113,14 +113,31 @@ METHODS
   reverse_dependencies
         my $deps = $mcpan->reverse_dependencies('ElasticSearch');
 
-    Return an array (ref) of MetaCPAN::Client::Release matching all releases
-    that are dependent on a given module.
+    all MetaCPAN::Client::Release objects of releases that are dependent on
+    a given module, returned as MetaCPAN::Client::ResultSet.
 
   rev_deps
     Alias to "reverse_dependencies" described above.
 
+  recent
+        my $recent = $mcpan->recent(10);
+        my $recent = $mcpan->recent('today');
+
+    return the latest N releases, or all releases from today.
+
+    returns a MetaCPAN::Client::ResultSet of MetaCPAN::Client::Release.
+
   pod
-    Not implemented yet.
+    Get POD for given file/module name. returns a MetaCPAN::Client::POD
+    object, which supports various output formats (html, plain, x_pod &
+    x_markdown).
+
+        my $pod = $mcpan->pod('Moo')->html;
+
+  all
+    Retrieve all matches for authors/modules/distributions or releases.
+
+        my $all_releases = $mcpan->all('releases')
 
   BUILDARGS
     Internal construction wrapper. Do not use.
@@ -129,8 +146,7 @@ SEARCH SPEC
     The hash-based search spec is common to many searches. It is quite
     feature-rich and allows to disambiguate different types of searches.
 
-  Simple
-    Simple searches just contain keys and values:
+    Basic search specs just contain a hash of keys and values:
 
         my $author = $mcpan->author( { name => 'Micha Nasriachi' } );
 
@@ -167,6 +183,20 @@ SEARCH SPEC
             ]
         } );
 
+    If you want to do something even more complicated, You can also nest
+    your queries, e.g.:
+
+        my $gmail_daves_or_cpan_sams = $mcpan->author( {
+            either => [
+                { all => [ { name => 'Dave *'  },
+                           { email => '*gmail.com' } ]
+                },
+                { all => [ { name => 'Sam *' },
+                           { email => '*cpan.org' } ]
+                },
+            ],
+        } );
+
   NOT
     If you want to filter out some of the results of an either/all query
     adding a *NOT* filter condition, such as "not these", you can use the
@@ -5,7 +5,7 @@ license = Perl_5
 copyright_holder = Sawyer X
 copyright_year   = 2014
 
-version = 1.003000
+version = 1.008000
 
 [@Basic]
 [PodSyntaxTests]
@@ -19,6 +19,11 @@ Search::Elasticsearch = 1.10
 [AutoPrereqs]
 skip = ^t::lib::Functions$
 
+[Prereqs::Soften]
+module = HTTP::Tiny::Mech
+module = WWW::Mechanize::Cached
+copy_to = develop.requires
+
 [ModuleBuild]
 [PodWeaver]
 [ReadmeFromPod]
@@ -1,3 +1,6 @@
+
+# examples/author-country.pl
+
 use strict;
 use warnings;
 use Data::Printer;
@@ -1,3 +1,7 @@
+
+
+# examples/author.pl
+
 use strict;
 use warnings;
 use Data::Printer;
@@ -15,3 +19,4 @@ my %output = (
 );
 
 p %output;
+
@@ -1,3 +1,6 @@
+
+# examples/complex-either-and.pl
+
 use strict;
 use warnings;
 use Data::Printer;
@@ -9,9 +12,7 @@ my $authors =
             { name => 'Dave *'  },
             { name => 'David *' },
         ],
-        all => [
-            { email => '*gmail.com' }
-        ],
+        all => { email => '*gmail.com' },
     });
 
 my %output = (
@@ -1,3 +1,6 @@
+
+# examples/complex-either-not.pl
+
 use strict;
 use warnings;
 use Data::Printer;
@@ -16,4 +19,5 @@ my $authors =
     });
 
 print "\n";
-p ( $authors->total );
+my %out = ( TOTAL => $authors->total );
+p %out;
@@ -0,0 +1,26 @@
+
+# examples/complex-nested-either-and.pl
+
+use strict;
+use warnings;
+use Data::Printer;
+use MetaCPAN::Client;
+
+my $authors =
+    MetaCPAN::Client->new->author({
+        either => [
+            { all => [ { name => 'Dave *'  },
+                       { email => '*gmail.com' } ]
+            },
+            { all => [ { name => 'Sam *' },
+                       { email => '*cpan.org' } ]
+            },
+        ],
+    });
+
+my %output = (
+    TOTAL => $authors->total,
+    NAMES => [ map { $authors->next->name } 0 .. 9 ],
+);
+
+p %output;
@@ -1,3 +1,6 @@
+
+# examples/complex.pl
+
 use strict;
 use warnings;
 use Data::Printer;
@@ -1,3 +1,6 @@
+
+# examples/distribution.pl
+
 use strict;
 use warnings;
 use Data::Printer;
@@ -0,0 +1,23 @@
+
+# examples/module.pl
+
+use strict;
+use warnings;
+use DDP;
+
+use MetaCPAN::Client;
+
+my $module =
+    MetaCPAN::Client->new->module('Moo');
+
+my %output = (
+    NAME        => $module->name,
+    ABSTRACT    => $module->abstract,
+    DESCRIPTION => $module->description,
+    RELEASE     => $module->release,
+    AUTHOR      => $module->author,
+    VERSION     => $module->version,
+);
+
+p %output;
+
@@ -0,0 +1,11 @@
+
+# examples/pod.pl
+
+use strict;
+use warnings;
+use MetaCPAN::Client;
+
+my $pod =
+    MetaCPAN::Client->new->pod('Moo');
+
+print $pod->html;
@@ -0,0 +1,22 @@
+
+# examples/recent.pl
+
+use strict;
+use warnings;
+use Data::Printer;
+use MetaCPAN::Client;
+
+my $recent =
+    MetaCPAN::Client->new->recent(3);
+
+while ( my $rel = $recent->next ) {
+    my %output = (
+        NAME    => $rel->name,
+        AUTHOR  => $rel->author,
+        DATE    => $rel->date,
+        VERSION => $rel->version,
+    );
+
+    p %output;
+}
+
@@ -0,0 +1,19 @@
+use strict;
+use warnings;
+use Data::Printer;
+use MetaCPAN::Client;
+
+my $recent =
+    MetaCPAN::Client->new->recent('today');
+
+while ( my $rel = $recent->next ) {
+    my %output = (
+        NAME    => $rel->name,
+        AUTHOR  => $rel->author,
+        DATE    => $rel->date,
+        VERSION => $rel->version,
+    );
+
+    p %output;
+}
+
@@ -1,3 +1,6 @@
+
+# examples/rev_deps-recursive.pl
+
 use strict;
 use warnings;
 use Term::ANSIColor;
@@ -5,7 +8,7 @@ use MetaCPAN::Client;
 
 $|=1;
 
-my $dist  = 'Hijk';
+my $dist  = shift || 'Hijk';
 my $mcpan = MetaCPAN::Client->new;
 
 print "\n\n", colored( "* $dist", 'green' ), "\n";
@@ -17,16 +20,16 @@ sub dig {
 
     my $res   = $mcpan->reverse_dependencies($dist);
 
-    for ( @{$res} ) {
+    while ( my $item = $res->next ) {
         if ( $level ) {
             printf "%s%s\n",
                 colored( '....' x $level, 'yellow' ),
-                $_->distribution;
+                $item->distribution;
         } else {
             printf "\n>> %s\n",
-                colored( $_->distribution, 'blue' );
+                colored( $item->distribution, 'blue' );
         }
 
-        dig( $_->distribution, $level + 1 );
+        dig( $item->distribution, $level + 1 );
     }
-};
+}
@@ -1,17 +1,26 @@
+
+# examples/rev_deps.pl
+
 use strict;
 use warnings;
 use Data::Printer;
 use MetaCPAN::Client;
 
+my $module = shift || 'Hijk';
+
 my $deps =
-    MetaCPAN::Client->new->rev_deps('Hijk');
+    MetaCPAN::Client->new->rev_deps($module);
+
+my @output;
 
-my @output = (
-    map +{
-        name   => $_->name,
-        author => $_->author,
-    },
-    @{$deps},
-);
+while ( my $rel = $deps->next ) {
+    push @output => {
+        name   => $rel->name,
+        author => $rel->author,
+    };
+}
 
+print "\n";
+my $title = "Reverse dependencies for 'Hijk':";
+p $title;
 p @output;
@@ -0,0 +1,17 @@
+use strict;
+use warnings;
+use Data::Printer;
+use MetaCPAN::Client;
+
+my $mcpan = MetaCPAN::Client->new;
+
+my $all_authors  = $mcpan->all('authors');
+my $all_dists    = $mcpan->all('distributions');
+my $all_modules  = $mcpan->all('modules');
+my $all_releases = $mcpan->all('releases');
+
+print "totals:\n";
+printf "authors       : %d\n", $all_authors->total;
+printf "distributions : %d\n", $all_dists->total;
+printf "modules       : %d\n", $all_modules->total;
+printf "releases      : %d\n", $all_releases->total;
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Author;
 # ABSTRACT: An Author data object
-$MetaCPAN::Client::Author::VERSION = '1.003000';
+$MetaCPAN::Client::Author::VERSION = '1.008000';
 use Moo;
 
 with 'MetaCPAN::Client::Role::Entity';
@@ -29,10 +29,7 @@ sub releases {
     my $self = shift;
     my $id   = $self->pauseid;
 
-    require MetaCPAN::Client;
-
-    return
-        MetaCPAN::Client->new->release({
+    return $self->client->release({
             all => [
                 { author => $id      },
                 { status => 'latest' },
@@ -46,13 +43,15 @@ __END__
 
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 MetaCPAN::Client::Author - An Author data object
 
 =head1 VERSION
 
-version 1.003000
+version 1.008000
 
 =head1 DESCRIPTION
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Distribution;
 # ABSTRACT: A Distribution data object
-$MetaCPAN::Client::Distribution::VERSION = '1.003000';
+$MetaCPAN::Client::Distribution::VERSION = '1.008000';
 use Moo;
 
 with 'MetaCPAN::Client::Role::Entity';
@@ -29,13 +29,15 @@ __END__
 
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 MetaCPAN::Client::Distribution - A Distribution data object
 
 =head1 VERSION
 
-version 1.003000
+version 1.008000
 
 =head1 DESCRIPTION
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Favorite;
 # ABSTRACT: A Favorite data object
-$MetaCPAN::Client::Favorite::VERSION = '1.003000';
+$MetaCPAN::Client::Favorite::VERSION = '1.008000';
 use Moo;
 
 with 'MetaCPAN::Client::Role::Entity';
@@ -29,13 +29,15 @@ __END__
 
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 MetaCPAN::Client::Favorite - A Favorite data object
 
 =head1 VERSION
 
-version 1.003000
+version 1.008000
 
 =head1 DESCRIPTION
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::File;
 # ABSTRACT: A File data object
-$MetaCPAN::Client::File::VERSION = '1.003000';
+$MetaCPAN::Client::File::VERSION = '1.008000';
 use Moo;
 use Carp;
 
@@ -52,13 +52,15 @@ __END__
 
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 MetaCPAN::Client::File - A File data object
 
 =head1 VERSION
 
-version 1.003000
+version 1.008000
 
 =head1 DESCRIPTION
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Module;
 # ABSTRACT: A Module data object
-$MetaCPAN::Client::Module::VERSION = '1.003000';
+$MetaCPAN::Client::Module::VERSION = '1.008000';
 use Moo;
 extends 'MetaCPAN::Client::File';
 
@@ -12,13 +12,15 @@ __END__
 
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 MetaCPAN::Client::Module - A Module data object
 
 =head1 VERSION
 
-version 1.003000
+version 1.008000
 
 =head1 DESCRIPTION
 
@@ -0,0 +1,108 @@
+use strict;
+use warnings;
+package MetaCPAN::Client::Pod;
+# ABSTRACT: A Pod object
+$MetaCPAN::Client::Pod::VERSION = '1.008000';
+use Moo;
+
+has name => ( is => 'ro', required => 1 );
+
+my @known_formats = qw<
+    html plain x_pod x_markdown
+>;
+
+foreach my $format (@known_formats) {
+    has $format => (
+        is      => 'ro',
+        lazy    => 1,
+        default => sub {
+            my $self = shift;
+            return $self->_request( $format );
+        },
+    );
+}
+
+sub _request {
+    my $self   = shift;
+    my $ctype  = shift || "plain";
+
+    $ctype =~ s/_/-/;
+
+    my $name = $self->name;
+
+    require MetaCPAN::Client::Request;
+
+    return
+        MetaCPAN::Client::Request->new->fetch(
+            "pod/${name}?content-type=text/${ctype}"
+        );
+}
+
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+MetaCPAN::Client::Pod - A Pod object
+
+=head1 VERSION
+
+version 1.008000
+
+=head1 SYNOPSIS
+
+  use strict;
+  use warnings;
+  use MetaCPAN::Client;
+  
+  my $pod = MetaCPAN::Client->new->pod('Moo');
+  
+  print $pod->html;
+
+=head1 DESCRIPTION
+
+=head1 ATTRIBUTES
+
+=head2 name
+
+=head2 x_pod
+
+=head2 html
+
+=head2 x_markdown
+
+=head2 plain
+
+Get the plaintext version of the documentation
+
+  $pod = MetaCPAN::Client->new->pod( "MetaCPAN::Client" );
+  print $pod->plain;
+
+=head1 AUTHORS
+
+=over 4
+
+=item *
+
+Sawyer X <xsawyerx@cpan.org>
+
+=item *
+
+Mickey Nasriachi <mickey@cpan.org>
+
+=back
+
+=head1 COPYRIGHT AND LICENSE
+
+This software is copyright (c) 2014 by Sawyer X.
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
+=cut
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Rating;
 # ABSTRACT: A Rating data object
-$MetaCPAN::Client::Rating::VERSION = '1.003000';
+$MetaCPAN::Client::Rating::VERSION = '1.008000';
 use Moo;
 
 with 'MetaCPAN::Client::Role::Entity';
@@ -31,13 +31,15 @@ __END__
 
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 MetaCPAN::Client::Rating - A Rating data object
 
 =head1 VERSION
 
-version 1.003000
+version 1.008000
 
 =head1 DESCRIPTION
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Release;
 # ABSTRACT: A Release data object
-$MetaCPAN::Client::Release::VERSION = '1.003000';
+$MetaCPAN::Client::Release::VERSION = '1.008000';
 use Moo;
 
 with 'MetaCPAN::Client::Role::Entity';
@@ -10,7 +10,7 @@ with 'MetaCPAN::Client::Role::Entity';
 my @known_fields = qw<
     resources status date author maturity dependency id authorized
     download_url first archive version name version_numified license
-    distribution stat provides tests abstract
+    distribution stat provides tests abstract metadata
 >;
 
 foreach my $field (@known_fields) {
@@ -32,57 +32,61 @@ __END__
 
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 MetaCPAN::Client::Release - A Release data object
 
 =head1 VERSION
 
-version 1.003000
+version 1.008000
 
 =head1 DESCRIPTION
 
 =head1 ATTRIBUTES
 
-#head2 resources
+=head2 resources
+
+=head2 status
 
-#head2 status
+=head2 date
 
-#head2 date
+=head2 author
 
-#head2 author
+=head2 maturity
 
-#head2 maturity
+=head2 dependency
 
-#head2 dependency
+=head2 id
 
-#head2 id
+=head2 authorized
 
-#head2 authorized
+=head2 download_url
 
-#head2 download_url
+=head2 first
 
-#head2 first
+=head2 archive
 
-#head2 archive
+=head2 version
 
-#head2 version
+=head2 name
 
-#head2 name
+=head2 version_numified
 
-#head2 version_numified
+=head2 license
 
-#head2 license
+=head2 distribution
 
-#head2 distribution
+=head2 stat
 
-#head2 stat
+=head2 provides
 
-#head2 provides
+=head2 tests
 
-#head2 tests
+=head2 abstract
 
-#head2 abstract
+=head2 metadata
 
 =head1 AUTHORS
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Request;
 # ABSTRACT: Object used for making requests to MetaCPAN
-$MetaCPAN::Client::Request::VERSION = '1.003000';
+$MetaCPAN::Client::Request::VERSION = '1.008000';
 use Moo;
 use Carp;
 use JSON::MaybeXS qw<decode_json encode_json>;
@@ -30,10 +30,17 @@ has base_url => (
     },
 );
 
+has _user_ua => (
+    init_arg  => 'ua',
+    is        => 'ro',
+    predicate => '_has_user_ua',
+);
+
 has ua => (
-    is      => 'ro',
-    lazy    => 1,
-    builder => '_build_ua',
+    init_arg => undef,
+    is       => 'ro',
+    lazy     => 1,
+    builder  => '_build_ua',
 );
 
 has ua_args => (
@@ -45,6 +52,13 @@ has ua_args => (
 
 sub _build_ua {
     my $self = shift;
+    # This level of indirection is so that if a user has not specified a custom UA
+    # MetaCPAN::Client and ElasticSearch will have their own UA's
+    #
+    # But if the user **has** specified a custom UA, that UA is used for both.
+    if ( $self->_has_user_ua ) {
+      return $self->_user_ua;
+    }
     return HTTP::Tiny->new( @{ $self->ua_args } );
 }
 
@@ -72,6 +86,7 @@ sub ssearch {
         nodes            => $self->domain,
         cxn_pool         => 'Static::NoPing',
         send_get_body_as => 'POST',
+        ( $self->_has_user_ua ? ( handle => $self->_user_ua ) : () )
     );
 
     my $scroller = Search::Elasticsearch::Scroll->new(
@@ -120,7 +135,9 @@ sub _build_body {
     my $self  = shift;
     my $args  = shift;
 
-    my $query = _build_query_rec($args);
+    my $query = $args->{__MATCH_ALL__}
+        ? { match_all => {} }
+        : _build_query_rec($args);
 
     return +{ query => $query };
 }
@@ -140,6 +157,7 @@ sub _build_query_rec {
 
   KEY: for my $k ( qw/ all either not / ) {
         my $v = delete $args->{$k} || next KEY;
+        ref $v eq 'HASH'  and $v = [ $v ];
         ref $v eq 'ARRAY' or croak "invalid value for key $k";
 
         undef $basic_element;
@@ -179,13 +197,15 @@ __END__
 
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 MetaCPAN::Client::Request - Object used for making requests to MetaCPAN
 
 =head1 VERSION
 
-version 1.003000
+version 1.008000
 
 =head1 ATTRIBUTES
 
@@ -2,20 +2,10 @@ use strict;
 use warnings;
 package MetaCPAN::Client::ResultSet;
 # ABSTRACT: A Result Set
-$MetaCPAN::Client::ResultSet::VERSION = '1.003000';
+$MetaCPAN::Client::ResultSet::VERSION = '1.008000';
 use Moo;
 use Carp;
 
-has scroller => (
-    is       => 'ro',
-    isa      => sub {
-        ref $_[0] eq 'Search::Elasticsearch::Scroll'
-            or croak 'scroller must be an Search::Elasticsearch::Scroll object';
-    },
-    handles  => ['total'],
-    required => 1,
-);
-
 has type => (
     is       => 'ro',
     isa      => sub {
@@ -26,31 +16,64 @@ has type => (
     required => 1,
 );
 
-has facets => (
+# in case we're returning from a scrolled search
+has scroller => (
+    is        => 'ro',
+    isa       => sub {
+        use Safe::Isa;
+        $_[0]->$_isa('Search::Elasticsearch::Scroll')
+            or croak 'scroller must be an Search::Elasticsearch::Scroll object';
+    },
+    predicate => 'has_scroller',
+);
+
+# in case we're returning from a fetch
+has items => (
+    is  => 'ro',
+    isa => sub {
+        ref $_[0] eq 'ARRAY'
+            or croak 'items must be an array ref';
+    },
+);
+
+has total => (
     is      => 'ro',
-    lazy    => 1,
-    builder => '_get_facets',
+    default => sub {
+        my $self = shift;
+
+        return $self->has_scroller ? $self->scroller->total
+                                   : scalar @{ $self->items };
+    },
 );
 
-sub _get_facets {
-    my $self = shift;
+sub BUILDARGS {
+    my ( $class, %args ) = @_;
 
-    return $self->scroller->facets || {};
-}
+    exists $args{scroller} or exists $args{items}
+        or croak 'ResultSet must get either scroller or items';
+
+    exists $args{scroller} and exists $args{items}
+        and croak 'ResultSet must get either scroller or items, not both';
 
+    return \%args;
+}
 
 sub next {
     my $self   = shift;
-    my $result = $self->scroller->next;
+    my $result = $self->has_scroller ? $self->scroller->next
+                                     : shift @{ $self->items };
 
-    defined $result
-        or return;
+    defined $result or return;
 
     my $class = 'MetaCPAN::Client::' . ucfirst $self->type;
-
     return $class->new_from_request( $result->{'_source'} || $result->{'fields'} );
 }
 
+sub facets {
+    my $self = shift;
+
+    return $self->has_scroller ? $self->scroller->facets : {};
+}
 
 1;
 
@@ -58,25 +81,31 @@ __END__
 
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 MetaCPAN::Client::ResultSet - A Result Set
 
 =head1 VERSION
 
-version 1.003000
+version 1.008000
 
 =head1 DESCRIPTION
 
 Object representing a result from Elastic Search. This is used for the complex
-(as in non-simple) queries to MetaCPAN. It provides easy access to the scroller
-and facets.
+(as in L<non-simple/MetaCPAN::Client/"SEARCH SPEC">) queries to MetaCPAN. It
+provides easy access to the scroller and facets.
 
 =head1 ATTRIBUTES
 
 =head2 scroller
 
-An L<Search::Elasticsearch::Scroll> object
+An L<Search::Elasticsearch::Scroll> object.
+
+=head2 items
+
+An arrayref of items to manually scroll over, instead of a scroller object.
 
 =head2 type
 
@@ -112,6 +141,14 @@ Iterator call to fetch the next result set object.
 
 Iterator call to fetch the total amount of objects available in result set.
 
+=head2 has_scroller
+
+Predicate for ES scroller presence.
+
+=head2 BUILDARGS
+
+Double checks construction of objects. You should never run this yourself.
+
 =head1 AUTHORS
 
 =over 4
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client::Role::Entity;
 # ABSTRACT: A role for MetaCPAN entities
-$MetaCPAN::Client::Role::Entity::VERSION = '1.003000';
+$MetaCPAN::Client::Role::Entity::VERSION = '1.008000';
 use Moo::Role;
 
 has data => (
@@ -10,10 +10,22 @@ has data => (
     required => 1,
 );
 
+has client => (
+    is         => 'ro',
+    lazy       => 1,
+    builder    => '_build_client',
+);
+
+sub _build_client {
+    require MetaCPAN::Client;
+    return MetaCPAN::Client->new();
+}
+
 sub new_from_request {
-    my ( $class, $request ) = @_;
+    my ( $class, $request, $client ) = @_;
 
     return $class->new(
+        ( defined $client ? ( client => $client ) : () ),
         data => {
             map +( defined $request->{$_} ? ( $_ => $request->{$_} ) : () ),
             @{ $class->_known_fields }
@@ -27,13 +39,15 @@ __END__
 
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 MetaCPAN::Client::Role::Entity - A role for MetaCPAN entities
 
 =head1 VERSION
 
-version 1.003000
+version 1.008000
 
 =head1 DESCRIPTION
 
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 package MetaCPAN::Client;
 # ABSTRACT: A comprehensive, DWIM-featured client to the MetaCPAN API
-$MetaCPAN::Client::VERSION = '1.003000';
+$MetaCPAN::Client::VERSION = '1.008000';
 use Moo;
 use Carp;
 
@@ -12,6 +12,7 @@ use MetaCPAN::Client::Distribution;
 use MetaCPAN::Client::Module;
 use MetaCPAN::Client::File;
 use MetaCPAN::Client::Favorite;
+use MetaCPAN::Client::Pod;
 use MetaCPAN::Client::Rating;
 use MetaCPAN::Client::Release;
 use MetaCPAN::Client::ResultSet;
@@ -30,6 +31,8 @@ sub BUILDARGS {
 
     $args{'request'} ||= MetaCPAN::Client::Request->new(
         ( ua => $args{'ua'} ) x !! $args{'ua'},
+        $args{domain}  ? ( domain => $args{domain} )   : (),
+        $args{version} ? ( version => $args{version} ) : (),
     );
 
     return \%args;
@@ -69,6 +72,13 @@ sub file {
     return $self->_get( 'file', $path );
 }
 
+sub pod {
+    my $self = shift;
+    my $name = shift;
+
+    return MetaCPAN::Client::Pod->new({ name => $name });
+}
+
 #
 # $api->rating({ dist => "Moose" })
 #   is equal to http://api.metacpan.org/v0/favorite/_search?q=distribution:Moose
@@ -128,6 +138,36 @@ sub reverse_dependencies {
 
 *rev_deps = *reverse_dependencies;
 
+sub recent {
+    my $self = shift;
+    my $size = shift || 100;
+
+    $size eq 'today'
+        and return $self->_recent(
+            size   => 1000,
+            filter => _filter_today()
+        );
+
+    $size =~ /^[0-9]+$/
+        and return $self->_recent( size => $size );
+
+    croak "recent: invalid size value";
+}
+
+sub all {
+    my $self = shift;
+    my $type = shift;
+
+    my $match_all = { __MATCH_ALL__ => 1 };
+
+    $type eq 'authors'       and return $self->author( $match_all );
+    $type eq 'distributions' and return $self->distribution( $match_all );
+    $type eq 'modules'       and return $self->module( $match_all );
+    $type eq 'releases'      and return $self->release( $match_all );
+
+    croak "all: unsupported type";
+}
+
 ###
 
 sub _get {
@@ -144,7 +184,7 @@ sub _get {
         or croak sprintf( 'Failed to fetch %s (%s)', ucfirst($type), $arg );
 
     my $class = 'MetaCPAN::Client::' . ucfirst($type);
-    return $class->new_from_request($response);
+    return $class->new_from_request($response, $self);
 }
 
 sub _search {
@@ -197,23 +237,70 @@ sub _reverse_deps {
         $res = $self->fetch(
             '/search/reverse_dependencies/'.$dist,
             {
-                query  => { match_all => {} },
-                filter => { term => { 'release.status' => 'latest' } },
                 size   => 5000,
+                query  => { match_all => {} },
+                filter => {
+                    and => [
+                        { term => { 'release.status' => 'latest' } },
+                        { term => { 'authorized'     => \1       } },
+                    ]
+                },
             }
         );
+        1;
 
     } or do {
         warn $@;
-        return [];
+        return _empty_result_set('release'),
     };
 
-    return +[
-        map { MetaCPAN::Client::Release->new_from_request($_->{'_source'}) }
-        @{ $res->{'hits'}{'hits'} }
-    ];
+    return MetaCPAN::Client::ResultSet->new(
+        items => $res->{'hits'}{'hits'},
+        type  => 'release',
+    );
 }
 
+sub _recent {
+    my $self = shift;
+    my @args = @_;
+
+    my $res;
+
+    eval {
+        $res = $self->fetch(
+            '/release/_search',
+            {
+                from   => 0,
+                query  => { match_all => {} },
+                @args,
+                sort   => [ { 'date' => { order => "desc" } } ],
+            }
+        );
+        1;
+
+    } or do {
+        warn $@;
+        return _empty_result_set('release');
+    };
+
+    return MetaCPAN::Client::ResultSet->new(
+        items => $res->{'hits'}{'hits'},
+        type  => 'release',
+    );
+}
+
+sub _filter_today {
+    return { range => { date => { from => "now/1d+0h" } } };
+}
+
+sub _empty_result_set {
+    my $type = shift;
+
+    return MetaCPAN::Client::ResultSet->new(
+        items => [],
+        type  => $type,
+    );
+}
 
 1;
 
@@ -221,20 +308,22 @@ __END__
 
 =pod
 
+=encoding UTF-8
+
 =head1 NAME
 
 MetaCPAN::Client - A comprehensive, DWIM-featured client to the MetaCPAN API
 
 =head1 VERSION
 
-version 1.003000
+version 1.008000
 
 =head1 SYNOPSIS
 
     # simple usage
     my $mcpan  = MetaCPAN::Client->new();
     my $author = $mcpan->author('XSAWYERX');
-    my $dist   = $mcpan->distribuion('MetaCPAN-Client');
+    my $dist   = $mcpan->distribution('MetaCPAN-Client');
 
     # advanced usage with cache (contributed by Kent Fredric)
     use CHI;
@@ -289,7 +378,7 @@ under C<SEARCH SPEC>.
 
 Return a L<MetaCPAN::Client::Author> object on a simple search (PAUSE ID), or
 a L<MetaCPAN::Client::ResultSet> object propagated with
-L<MetaCPAN::Client::Author> objects on a complex (search spec based) search.
+L<MetaCPAN::Client::Author> objects on a complex (L<search spec based|/"SEARCH SPEC">) search.
 
 =head2 module
 
@@ -302,12 +391,12 @@ under C<SEARCH SPEC>.
 
 Return a L<MetaCPAN::Client::Module> object on a simple search (module name), or
 a L<MetaCPAN::Client::ResultSet> object propagated with
-L<MetaCPAN::Client::Module> objects on a complex (search spec based) search.
+L<MetaCPAN::Client::Module> objects on a complex (L<search spec based|/"SEARCH SPEC">) search.
 
 =head2 distribution
 
-    my $dist = $mcpan->dist('MetaCPAN-Client');
-    my $dist = $mcpan->dist($search_spec);
+    my $dist = $mcpan->distribution('MetaCPAN-Client');
+    my $dist = $mcpan->distribution($search_spec);
 
 Finds a distribution by either its distribution name or by a search spec
 defined by a hash reference. Since it is common to many other searches, it is
@@ -315,7 +404,7 @@ explained below under C<SEARCH SPEC>.
 
 Return a L<MetaCPAN::Client::Distribution> object on a simple search
 (distribution name), or a L<MetaCPAN::Client::ResultSet> object propagated with
-L<MetaCPAN::Client::Distribution> objects on a complex (search spec based)
+L<MetaCPAN::Client::Distribution> objects on a complex (L<search spec based|/"SEARCH SPEC">)
 search.
 
 =head2 file
@@ -341,22 +430,41 @@ below under C<SEARCH SPEC>.
 
 Return a L<MetaCPAN::Client::Release> object on a simple search (release name),
 or a L<MetaCPAN::Client::ResultSet> object propagated with
-L<MetaCPAN::Client::Release> objects on a complex (search spec based) search.
+L<MetaCPAN::Client::Release> objects on a complex (L<search spec based|/"SEARCH SPEC">) search.
 
 =head2 reverse_dependencies
 
     my $deps = $mcpan->reverse_dependencies('ElasticSearch');
 
-Return an array (ref) of L<MetaCPAN::Client::Release> matching all
-releases that are dependent on a given module.
+all L<MetaCPAN::Client::Release> objects of releases that are dependent
+on a given module, returned as L<MetaCPAN::Client::ResultSet>.
 
 =head2 rev_deps
 
 Alias to C<reverse_dependencies> described above.
 
+=head2 recent
+
+    my $recent = $mcpan->recent(10);
+    my $recent = $mcpan->recent('today');
+
+return the latest N releases, or all releases from today.
+
+returns a L<MetaCPAN::Client::ResultSet> of L<MetaCPAN::Client::Release>.
+
 =head2 pod
 
-Not implemented yet.
+Get POD for given file/module name.
+returns a L<MetaCPAN::Client::POD> object, which supports various output
+formats (html, plain, x_pod & x_markdown).
+
+    my $pod = $mcpan->pod('Moo')->html;
+
+=head2 all
+
+Retrieve all matches for authors/modules/distributions or releases.
+
+    my $all_releases = $mcpan->all('releases')
 
 =head2 BUILDARGS
 
@@ -367,9 +475,7 @@ Internal construction wrapper. Do not use.
 The hash-based search spec is common to many searches. It is quite
 feature-rich and allows to disambiguate different types of searches.
 
-=head2 Simple
-
-Simple searches just contain keys and values:
+Basic search specs just contain a hash of keys and values:
 
     my $author = $mcpan->author( { name => 'Micha Nasriachi' } );
 
@@ -408,6 +514,20 @@ key:
         ]
     } );
 
+If you want to do something even more complicated,
+You can also nest your queries, e.g.:
+
+    my $gmail_daves_or_cpan_sams = $mcpan->author( {
+        either => [
+            { all => [ { name => 'Dave *'  },
+                       { email => '*gmail.com' } ]
+            },
+            { all => [ { name => 'Sam *' },
+                       { email => '*cpan.org' } ]
+            },
+        ],
+    } );
+
 =head2 NOT
 
 If you want to filter out some of the results of an either/all query
@@ -2,9 +2,9 @@ use 5.006;
 use strict;
 use warnings;
 
-# this test was generated with Dist::Zilla::Plugin::Test::Compile 2.040
+# this test was generated with Dist::Zilla::Plugin::Test::Compile 2.045
 
-use Test::More  tests => 11 + ($ENV{AUTHOR_TESTING} ? 1 : 0);
+use Test::More  tests => 12 + ($ENV{AUTHOR_TESTING} ? 1 : 0);
 
 
 
@@ -15,6 +15,7 @@ my @module_files = (
     'MetaCPAN/Client/Favorite.pm',
     'MetaCPAN/Client/File.pm',
     'MetaCPAN/Client/Module.pm',
+    'MetaCPAN/Client/Pod.pm',
     'MetaCPAN/Client/Rating.pm',
     'MetaCPAN/Client/Release.pm',
     'MetaCPAN/Client/Request.pm',
@@ -0,0 +1,16 @@
+#!perl
+
+use strict;
+use warnings;
+use Test::More tests => 5;
+
+use t::lib::Functions;
+
+my $mc = mcpan();
+can_ok( $mc, 'pod' );
+
+my $pod = $mc->pod('MetaCPAN::API');
+isa_ok( $pod, 'MetaCPAN::Client::Pod' );
+can_ok( $pod, qw<html x_pod x_markdown plain name> );
+like( $pod->x_pod, qr/=head1/, 'got pod' );
+
@@ -3,7 +3,8 @@
 use strict;
 use warnings;
 
-use Test::More tests => 7;
+use Test::More tests => 9;
+use MetaCPAN::Client;
 use MetaCPAN::Client::Request;
 
 my $req = MetaCPAN::Client::Request->new( domain => 'mydomain', version => 'z' );
@@ -27,3 +28,6 @@ is_deeply(
     'Correct UA args',
 );
 
+my $client = MetaCPAN::Client->new( domain => 'foo', version => 'bar' );
+is ( $client->request->domain, 'foo', 'domain set in request' );
+is ( $client->request->version, 'bar', 'version set in request' );
@@ -7,11 +7,17 @@ use Test::More tests => 3;
 use Test::Fatal;
 use MetaCPAN::Client::ResultSet;
 
+{
+    package MetaCPAN::Client::Test::ScrollerZ;
+    use base 'Search::Elasticsearch::Scroll'; # < 5.10 FTW (except, no)
+    sub total {0}
+}
+
 like(
     exception {
         MetaCPAN::Client::ResultSet->new(
             type     => 'failZZ',
-            scroller => bless {}, 'Search::Elasticsearch::Scroll',
+            scroller => bless {}, 'MetaCPAN::Client::Test::ScrollerZ',
         )
     },
     qr/Invalid type/,
@@ -0,0 +1,51 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+# ABSTRACT: Make sure passed value of UA gets used for things.
+
+use Test::Requires {
+    'WWW::Mechanize::Cached' => 0,
+    'HTTP::Tiny::Mech'       => 0,
+};
+use Test::Fatal qw( exception );
+
+{
+
+    package TrapUA;
+    use Moo;
+    extends 'HTTP::Tiny::Mech';
+
+    sub mechua {
+        require WWW::Mechanize::Cached;
+        return WWW::Mechanize::Cached->new();
+    }
+}
+
+{
+    require HTTP::Tiny;
+    no warnings "redefine";
+    *HTTP::Tiny::request = sub {
+        my ( $self, @args ) = @_;
+        die "Illegal use of HTTP::Tiny" . pp( \@args );
+    };
+}
+use MetaCPAN::Client;
+
+my $e;
+is(
+    $e = exception {
+        my $client = MetaCPAN::Client->new( ua => TrapUA->new() );
+
+        my $a        = $client->author('KENTNL');
+        my $releases = $a->releases;
+    },
+    undef,
+    "No illegal methods called"
+);
+
+if ($e) { diag explain $e }
+
+done_testing;
+