File Coverage

blib/lib/GraphQL/Type/Union.pm
Criterion Covered Total %
statement 62 62 100.0
branch 12 20 60.0
condition n/a
subroutine 15 16 93.7
pod 2 2 100.0
total 91 100 91.0


line stmt bran cond sub pod time code
1             package GraphQL::Type::Union;
2              
3 3     3   3438 use 5.014;
  3         11  
4 3     3   18 use strict;
  3         6  
  3         68  
5 3     3   15 use warnings;
  3         8  
  3         76  
6 3     3   16 use Moo;
  3         6  
  3         18  
7 3     3   1109 use MooX::Thunking;
  3         13  
  3         25  
8 3     3   410 use Types::Standard -all;
  3         16  
  3         23  
9 3     3   145031 use GraphQL::Type::Library -all;
  3         8  
  3         32  
10 3     3   42812 use GraphQL::MaybeTypeCheck;
  3         8  
  3         22  
11 3     3   19 use GraphQL::Debug qw(_debug);
  3         6  
  3         297  
12             extends qw(GraphQL::Type);
13             with qw(
14             GraphQL::Role::Output
15             GraphQL::Role::Composite
16             GraphQL::Role::Abstract
17             GraphQL::Role::Nullable
18             GraphQL::Role::Named
19             );
20              
21 3     3   21 use constant DEBUG => $ENV{GRAPHQL_DEBUG};
  3         8  
  3         1021  
22              
23             our $VERSION = '0.02';
24              
25             =head1 NAME
26              
27             GraphQL::Type::Union - GraphQL union type
28              
29             =head1 SYNOPSIS
30              
31             use GraphQL::Type::Union;
32             my $union_type = GraphQL::Type::Union->new(
33             name => 'Union',
34             types => [ $type1, $type2 ],
35             resolve_type => sub {
36             return $type1 if ref $_[0] eq 'Type1';
37             return $type2 if ref $_[0] eq 'Type2';
38             },
39             );
40              
41             =head1 ATTRIBUTES
42              
43             Inherits C<name>, C<description> from L<GraphQL::Type>.
44              
45             =head2 types
46              
47             Thunked array-ref of L<GraphQL::Type::Object> objects.
48              
49             =cut
50              
51             has types => (
52             is => 'thunked',
53             isa => UniqueByProperty['name'] & ArrayRefNonEmpty[InstanceOf['GraphQL::Type::Object']],
54             required => 1,
55             );
56              
57             =head2 resolve_type
58              
59             Optional code-ref. Input is a value, returns a GraphQL type object for
60             it. If not given, relies on its possible type objects having a provided
61             C<is_type_of>.
62              
63             =cut
64              
65             has resolve_type => (is => 'ro', isa => CodeRef);
66              
67             =head1 METHODS
68              
69             =head2 get_types
70              
71             Returns list of L<GraphQL::Type::Object>s of which the object is a union,
72             performing validation.
73              
74             =cut
75              
76             has _types_validated => (is => 'rw', isa => Bool);
77 11 50   11 1 38 method get_types() :ReturnType(ArrayRefNonEmpty[InstanceOf['GraphQL::Type::Object']]) {
  11 50       35  
  11         20  
  11         18  
78 11         22 my @types = @{ $self->types };
  11         296  
79 10         1292 DEBUG and _debug('Union.get_types', $self->name, \@types);
80 10 100       175 return \@types if $self->_types_validated; # only do once
81 6         143 $self->_types_validated(1);
82 6 100       192 if (!$self->resolve_type) {
83 1         8 my @bad = map $_->name, grep !$_->is_type_of, @types;
84 1 50       6 die $self->name." no resolve_type and no is_type_of for @bad" if @bad;
85             }
86 6         25 \@types;
87 3     3   23 }
  3         7  
  3         25  
88              
89             method from_ast(
90             HashRef $name2type,
91             HashRef $ast_node,
92 5 50   5 1 20 ) :ReturnType(InstanceOf[__PACKAGE__]) {
  5 50       16  
  5 50       12  
  5 50       10  
  5         18  
  5         78  
  5         35  
93 5         9 DEBUG and _debug('Union.from_ast', $ast_node);
94             $self->new(
95             $self->_from_ast_named($ast_node),
96       0     resolve_type => sub {}, # fake
97 5         20 $self->_from_ast_maptype($name2type, $ast_node, 'types'),
98             );
99 3     3   5791 }
  3         6  
  3         19  
100              
101             has to_doc => (is => 'lazy', isa => Str);
102             sub _build_to_doc {
103 4     4   326 my ($self) = @_;
104 4         9 DEBUG and _debug('Union.to_doc', $self);
105             join '', map "$_\n",
106             ($self->description ? (map "# $_", split /\n/, $self->description) : ()),
107 4 50       18 "union @{[$self->name]} = " . join(' | ', map $_->name, @{$self->{types}});
  4         46  
  4         95  
108             }
109              
110             __PACKAGE__->meta->make_immutable();
111              
112             1;