File Coverage

blib/lib/GraphQL/Type/InputObject.pm
Criterion Covered Total %
statement 94 95 98.9
branch 20 38 52.6
condition 2 3 66.6
subroutine 23 23 100.0
pod 5 5 100.0
total 144 164 87.8


line stmt bran cond sub pod time code
1             package GraphQL::Type::InputObject;
2              
3 5     5   5517 use 5.014;
  5         18  
4 5     5   25 use strict;
  5         10  
  5         110  
5 5     5   33 use warnings;
  5         10  
  5         151  
6 5     5   23 use Moo;
  5         10  
  5         38  
7 5     5   2018 use Types::Standard -all;
  5         23  
  5         57  
8 5     5   216313 use GraphQL::Type::Library -all;
  5         14  
  5         46  
9 5     5   65471 use GraphQL::MaybeTypeCheck;
  5         13  
  5         46  
10 5     5   33 use GraphQL::Debug qw(_debug);
  5         11  
  5         531  
11             extends qw(GraphQL::Type);
12             with qw(
13             GraphQL::Role::Input
14             GraphQL::Role::Nullable
15             GraphQL::Role::Named
16             GraphQL::Role::FieldsInput
17             GraphQL::Role::HashMappable
18             GraphQL::Role::FieldsEither
19             );
20              
21             our $VERSION = '0.02';
22 5     5   32 use constant DEBUG => $ENV{GRAPHQL_DEBUG};
  5         11  
  5         440  
23              
24             =head1 NAME
25              
26             GraphQL::Type::InputObject - GraphQL input object type
27              
28             =head1 SYNOPSIS
29              
30             use GraphQL::Type::InputObject;
31             my $type = GraphQL::Type::InputObject->new(
32             name => 'InputObject',
33             fields => { field_name => { type => $scalar_type, resolve => sub { '' } }},
34             );
35              
36             =head1 ATTRIBUTES
37              
38             Has C<name>, C<description> from L<GraphQL::Role::Named>.
39             Has C<fields> from L<GraphQL::Role::FieldsInput>.
40              
41             =head1 METHODS
42              
43             =head2 is_valid
44              
45             True if given Perl hash-ref is a valid value for this type.
46              
47             =cut
48              
49 1 50   1 1 180 method is_valid(Maybe[HashRef] $item) :ReturnType(Bool) {
  1 50       6  
  1 50       10  
  1         5  
  1         6  
  6         6419  
50 6 50       15 return 1 if !defined $item;
51 6         43 my $fields = $self->fields;
52             return if grep !$fields->{$_}{type}->is_valid(
53             $item->{$_} // $fields->{$_}{default_value}
54 19 50 66     584 ), keys %$fields;
55 19         66 1;
56 5     5   2138 }
  5         11  
  5         44  
57              
58             =head2 uplift
59              
60             Turn given Perl entity into valid value for this type if possible. Applies
61             default values.
62              
63             =cut
64              
65 18 50   18 1 150 method uplift(Maybe[HashRef] $item) :ReturnType(Maybe[HashRef]) {
  18 50       61  
  18 50       479  
  18         2163  
  62         160  
  62         514  
66 5 100       5085 return $item if !defined $item;
67 5         15 my $fields = $self->fields;
68             $self->hashmap($item, $fields, sub {
69 19     62   74 my ($key, $value) = @_;
70             $fields->{$key}{type}->uplift(
71             $value // $fields->{$key}{default_value}
72 19         78 );
73 5         23 });
74 18     5   38 }
  18         42  
  18         55  
75              
76 0 50   19 1 0 method graphql_to_perl(ExpectObject $item) :ReturnType(Maybe[HashRef]) {
  17 50       162  
  17 50       53  
  17         77  
  15         482  
  15         536  
77 54 50       291 return $item if !defined $item;
78 5         5174 $item = $self->uplift($item);
79 5         17 my $fields = $self->fields;
80             $self->hashmap($item, $fields, sub {
81 1     54   6 $fields->{$_[0]}{type}->graphql_to_perl($_[1]);
82 5         22 });
83 19     5   48 }
  19         48  
  19         74  
84              
85 1 50   1 1 17 method perl_to_graphql(ExpectObject $item) :ReturnType(Maybe[HashRef]) {
  1 50       13  
  1 50       4  
  1         32  
  1         23  
  1         29  
86 1 50       18 return $item if !defined $item;
87 5         5368 $item = $self->uplift($item);
88 5         12 my $fields = $self->fields;
89             $self->hashmap($item, $fields, sub {
90 5     1   27 $fields->{$_[0]}{type}->perl_to_graphql($_[1]);
91 5         28 });
92 1     5   7 }
  1         3  
  1         3  
93              
94             method from_ast(
95             HashRef $name2type,
96             HashRef $ast_node,
97 5 50   5 1 21 ) :ReturnType(InstanceOf[__PACKAGE__]) {
  5 50       95  
  5         36  
  5         30  
  4         378  
  4         10  
  4         92  
98 4         16 $self->new(
99             $self->_from_ast_named($ast_node),
100             $self->_from_ast_fields($name2type, $ast_node, 'fields'),
101             );
102 5     5   21 }
  5         13  
  5         16  
103              
104             has to_doc => (is => 'lazy', isa => Str);
105             sub _build_to_doc {
106 4     4   14 my ($self) = @_;
107 4         28 DEBUG and _debug('InputObject.to_doc', $self);
108             my @fieldlines = map {
109 4         125 my ($main, @description) = @$_;
110             (
111             @description,
112             $main,
113             )
114             } $self->_make_fieldtuples($self->fields);
115             join '', map "$_\n",
116             $self->_description_doc_lines($self->description),
117             "input @{[$self->name]} {",
118             (map length() ? " $_" : "", @fieldlines),
119             "}";
120             }
121              
122             __PACKAGE__->meta->make_immutable();
123              
124             1;