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