File Coverage

lib/Web/NewsAPI/Result.pm
Criterion Covered Total %
statement 32 44 72.7
branch 2 6 33.3
condition n/a
subroutine 8 11 72.7
pod 3 5 60.0
total 45 66 68.1


line stmt bran cond sub pod time code
1             package Web::NewsAPI::Result;
2              
3 1     1   7 use Moose;
  1         1  
  1         7  
4              
5 1     1   7165 use Web::NewsAPI::Article;
  1         3  
  1         841  
6              
7             has 'page' => (
8             is => 'rw',
9             isa => 'Int',
10             default => 1,
11             trigger => sub { $_[0]->reset },
12             );
13              
14             has 'page_size' => (
15             is => 'rw',
16             isa => 'Int',
17             default => 20,
18             trigger => sub { $_[0]->reset },
19             );
20              
21             has 'total_results' => (
22             is => 'rw',
23             isa => 'Int',
24             lazy_build => 1,
25             clearer => 'clear_total_results',
26             );
27              
28             has 'articles_ref' => (
29             is => 'rw',
30             isa => 'ArrayRef[Web::NewsAPI::Article]',
31             lazy_build => 1,
32             clearer => 'clear_articles_ref',
33             );
34              
35             has 'query_results' => (
36             is => 'rw',
37             isa => 'HashRef',
38             lazy_build => 1,
39             clearer => 'clear_query_results',
40             );
41              
42             has 'newsapi' => (
43             is => 'ro',
44             required => 1,
45             isa => 'Web::NewsAPI',
46             );
47              
48             has 'api_endpoint' => (
49             is => 'ro',
50             required => 1,
51             isa => 'Str',
52             );
53              
54             has 'api_args' => (
55             is => 'ro',
56             isa => 'HashRef',
57             required => 1,
58             );
59              
60             sub BUILD {
61 5     5 0 1581 my $self = shift;
62              
63 5 50       155 if ( defined $self->api_args->{pageSize} ) {
64             $self->page_size( $self->api_args->{pageSize} )
65 0         0 }
66              
67 5 50       126 if ( defined $self->api_args->{page} ) {
68             $self->page( $self->api_args->{page} )
69 0         0 }
70              
71 5         11 return $self;
72             }
73              
74             sub articles {
75 5     5 1 25 my $self = shift;
76              
77 5         7 return @{ $self->articles_ref };
  5         136  
78             }
79              
80             sub turn_page {
81 0     0 1 0 my $self = shift;
82              
83 0         0 $self->page( $self->page + 1 );
84             }
85              
86             sub turn_page_back {
87 0     0 1 0 my $self = shift;
88              
89 0 0       0 if ( $self->page > 1 ) {
90 0         0 $self->page( $self->page - 1 );
91             }
92             }
93              
94             sub _build_articles_ref {
95 5     5   10 my $self = shift;
96              
97 5         9 my @articles;
98              
99 5         8 for my $article_data (@{ $self->query_results->{articles} }) {
  5         134  
100             push @articles, Web::NewsAPI::Article->new(
101             %$article_data,
102             source => Web::NewsAPI::Source->new(
103             id => $article_data->{source}->{id},
104             name => $article_data->{source}->{name},
105 8         5158 ),
106             );
107             }
108              
109 4         3981 return \@articles;
110             };
111              
112             sub _build_query_results {
113 5     5   10 my $self = shift;
114              
115 5         8 my %args = %{ $self->api_args };
  5         124  
116 5         140 $args{ pageSize } = $self->page_size;
117 5         172 $args{ page } = $self->page;
118              
119 5         132 my ($articles, $total_results) =
120             $self->newsapi->_request(
121             $self->api_endpoint,
122             'articles',
123             %args,
124             )
125             ;
126              
127             return {
128 4         150 articles => $articles,
129             total_results => $total_results,
130             };
131             }
132              
133             sub _build_total_results {
134 3     3   8 my $self = shift;
135              
136 3         84 return $self->query_results->{total_results};
137             }
138              
139             sub _make_articles {
140 0     0   0 my ($self, @article_data) = @_;
141 0         0 my @articles;
142 0         0 for my $article_data (@article_data) {
143             push @articles, Web::NewsAPI::Article->new(
144             %$article_data,
145             source => Web::NewsAPI::Source->new(
146             id => $article_data->{source}->{id},
147             name => $article_data->{source}->{name},
148 0         0 ),
149             );
150             }
151 0         0 return @articles;
152             }
153              
154             sub reset {
155 10     10 0 20 my $self = shift;
156              
157 10         324 $self->clear_articles_ref;
158 10         305 $self->clear_query_results;
159 10         295 $self->clear_total_results;
160             }
161              
162             1;
163              
164             =head1 NAME
165              
166             Web::NewsAPI::Result - Object representing a News API query result.
167              
168             =head1 SYNOPSIS
169              
170             use v5.10;
171             use Web::NewsAPI;
172              
173             my $newsapi = Web::NewsAPI->new(
174             api_key => $my_secret_api_key,
175             );
176              
177             say "Here are some top American-news headlines about science...";
178             my $result = $newsapi->top_headlines(
179             category => 'science', country => 'us',
180             );
181              
182             my $count = $result->total_results;
183             say "There are $count such headlines in the news right now.";
184              
185             say "Here are the top headlines...";
186             print_articles();
187              
188             say "And here's page two...";
189             $result->turn_page;
190             print_articles();
191              
192             sub print_articles {
193             for my $article ( $result->articles ) {
194             say $article->title;
195             say $article->description;
196             print "\n";
197             }
198             }
199              
200             =head1 DESCRIPTION
201              
202             Objects of this class represent the result of a News API query, such as
203             C<top-headlines> or C<everything>. Generally, you won't create these
204             objects yourself; you'll get them as a result of calling L<methods on a
205             Web::NewsAPI object|Web::NewsAPI/"Object methods">.
206              
207             An Web::NewsAPI::Result object gives you methods to retrieve one "page" of
208             articles, change the current page or page-size, and get the count of all
209             articles in the current set.
210              
211             =head1 METHODS
212              
213             =head2 Object attributes
214              
215             =head3 page
216              
217             my $current_page = $result->page;
218             $result->page( 2 );
219              
220             The current page of results that L<"artciles"> will return, expressed as
221             an integer.
222              
223             Default: 1.
224              
225             =head3 page_size
226              
227             my $page_size = $result->page_size;
228             $result->page_size( 10 );
229              
230             How many articles to return per call to L<"articles">.
231              
232             Default: 20.
233              
234             =head2 Object methods
235              
236             =head3 articles
237              
238             my @articles = $result->articles;
239              
240             Returns all the L<Web::NewsAPI::Article> objects that constitute the
241             current page of results.
242              
243             =head3 total_results
244              
245             my $count = $result->total_results;
246              
247             Returns the total number of results that News API has for the given
248             query parameters.
249              
250             =head3 turn_page
251              
252             $result->turn_page;
253              
254             Increment the current page.
255              
256             =head3 turn_page_back
257              
258             $result->turn_page_back;
259              
260             Decrement the current page, unless the current page number is already 1.
261              
262             =head1 NOTES
263              
264             Note that, due to the essential nature of News API, the size and
265             contents of a given article set can shift in between page-turns (or
266             page-size changes).
267              
268             For example: Say that you create an article set through a call to
269             L<Web::NewsAPI/"top_articles">, and view the first page of results. If
270             you call L<"turn_page"> and list the articles again, there is a chance
271             that one or more articles towards the end of the first page's list now
272             lead the second page's list. This can occur when I<more news has
273             happened> in between the first page's query and the second, effectively
274             causing new entries at the top of the first page and pushing all the
275             older results down.
276              
277             This sort of behavior occurs due to the nature of news, and software
278             using this module should be aware of it.
279              
280             =head1 AUTHOR
281              
282             Jason McIntosh (jmac@jmac.org)
283