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   3531 use 5.014;
  3         12  
4 3     3   17 use strict;
  3         6  
  3         69  
5 3     3   16 use warnings;
  3         6  
  3         79  
6 3     3   15 use Moo;
  3         6  
  3         22  
7 3     3   1156 use MooX::Thunking;
  3         7  
  3         26  
8 3     3   425 use Types::Standard -all;
  3         8  
  3         27  
9 3     3   127100 use GraphQL::Type::Library -all;
  3         7  
  3         60  
10 3     3   38630 use GraphQL::MaybeTypeCheck;
  3         7  
  3         30  
11 3     3   17 use GraphQL::Debug qw(_debug);
  3         8  
  3         284  
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   18 use constant DEBUG => $ENV{GRAPHQL_DEBUG};
  3         8  
  3         981  
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       32  
  11         23  
  11         20  
78 11         21 my @types = @{ $self->types };
  11         250  
79 10         1158 DEBUG and _debug('Union.get_types', $self->name, \@types);
80 10 100       149 return \@types if $self->_types_validated; # only do once
81 6         134 $self->_types_validated(1);
82 6 100       199 if (!$self->resolve_type) {
83 1         6 my @bad = map $_->name, grep !$_->is_type_of, @types;
84 1 50       4 die $self->name." no resolve_type and no is_type_of for @bad" if @bad;
85             }
86 6         26 \@types;
87 3     3   24 }
  3         5  
  3         24  
88              
89             method from_ast(
90             HashRef $name2type,
91             HashRef $ast_node,
92 5 50   5 1 28 ) :ReturnType(InstanceOf[__PACKAGE__]) {
  5 50       20  
  5 50       13  
  5 50       12  
  5         18  
  5         88  
  5         42  
93 5         10 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         29 $self->_from_ast_maptype($name2type, $ast_node, 'types'),
98             );
99 3     3   6034 }
  3         8  
  3         12  
100              
101             has to_doc => (is => 'lazy', isa => Str);
102             sub _build_to_doc {
103 4     4   361 my ($self) = @_;
104 4         11 DEBUG and _debug('Union.to_doc', $self);
105             join '', map "$_\n",
106             ($self->description ? (map "# $_", split /\n/, $self->description) : ()),
107 4 50       23 "union @{[$self->name]} = " . join(' | ', map $_->name, @{$self->{types}});
  4         23  
  4         97  
108             }
109              
110             __PACKAGE__->meta->make_immutable();
111              
112             1;