28
28
GraphQLString ,
29
29
)
30
30
31
-
32
- def resolve_null_sync (_obj , _info ) -> None :
33
- """A resolver returning a null value synchronously."""
34
- return
35
-
36
-
37
- async def resolve_null_async (_obj , _info ) -> None :
38
- """A resolver returning a null value asynchronously."""
39
- return
40
-
41
-
42
31
friend_type = GraphQLObjectType (
43
32
"Friend" ,
44
33
{
45
34
"id" : GraphQLField (GraphQLID ),
46
35
"name" : GraphQLField (GraphQLString ),
47
- "asyncNonNullErrorField" : GraphQLField (
48
- GraphQLNonNull (GraphQLString ), resolve = resolve_null_async
49
- ),
36
+ "nonNullName" : GraphQLField (GraphQLNonNull (GraphQLString )),
37
+ },
38
+ )
39
+
40
+ hero_type = GraphQLObjectType (
41
+ "Hero" ,
42
+ {
43
+ "id" : GraphQLField (GraphQLID ),
44
+ "name" : GraphQLField (GraphQLString ),
45
+ "nonNullName" : GraphQLField (GraphQLNonNull (GraphQLString )),
46
+ "friends" : GraphQLField (GraphQLList (friend_type )),
50
47
},
51
48
)
52
49
50
+ query = GraphQLObjectType ("Query" , {"hero" : GraphQLField (hero_type )})
51
+
52
+ schema = GraphQLSchema (query )
53
+
53
54
54
55
class Friend (NamedTuple ):
55
56
id : int
@@ -58,57 +59,44 @@ class Friend(NamedTuple):
58
59
59
60
friends = [Friend (2 , "Han" ), Friend (3 , "Leia" ), Friend (4 , "C-3PO" )]
60
61
62
+ hero = {"id" : 1 , "name" : "Luke" , "friends" : friends }
61
63
62
- async def resolve_slow (_obj , _info ) -> str :
63
- """Simulate a slow async resolver returning a value."""
64
- await sleep (0 )
65
- return "slow"
66
64
65
+ class Resolvers :
66
+ """Various resolver functions for testing."""
67
67
68
- async def resolve_bad (_obj , _info ) -> str :
69
- """Simulate a bad async resolver raising an error."""
70
- raise RuntimeError ("bad" )
68
+ @staticmethod
69
+ def null (_info ) -> None :
70
+ """A resolver returning a null value synchronously."""
71
+ return
71
72
73
+ @staticmethod
74
+ async def null_async (_info ) -> None :
75
+ """A resolver returning a null value asynchronously."""
76
+ return
72
77
73
- async def resolve_friends_async (_obj , _info ) -> AsyncGenerator [Friend , None ]:
74
- """A slow async generator yielding the first friend."""
75
- await sleep (0 )
76
- yield friends [0 ]
78
+ @staticmethod
79
+ async def slow (_info ) -> str :
80
+ """Simulate a slow async resolver returning a value."""
81
+ await sleep (0 )
82
+ return "slow"
77
83
84
+ @staticmethod
85
+ def bad (_info ) -> str :
86
+ """Simulate a bad resolver raising an error."""
87
+ raise RuntimeError ("bad" )
78
88
79
- hero_type = GraphQLObjectType (
80
- "Hero" ,
81
- {
82
- "id" : GraphQLField (GraphQLID ),
83
- "name" : GraphQLField (GraphQLString ),
84
- "slowField" : GraphQLField (GraphQLString , resolve = resolve_slow ),
85
- "errorField" : GraphQLField (GraphQLString , resolve = resolve_bad ),
86
- "nonNullErrorField" : GraphQLField (
87
- GraphQLNonNull (GraphQLString ), resolve = resolve_null_sync
88
- ),
89
- "asyncNonNullErrorField" : GraphQLField (
90
- GraphQLNonNull (GraphQLString ), resolve = resolve_null_async
91
- ),
92
- "friends" : GraphQLField (
93
- GraphQLList (friend_type ), resolve = lambda _obj , _info : friends
94
- ),
95
- "asyncFriends" : GraphQLField (
96
- GraphQLList (friend_type ), resolve = resolve_friends_async
97
- ),
98
- },
99
- )
100
-
101
- hero = Friend (1 , "Luke" )
102
-
103
- query = GraphQLObjectType (
104
- "Query" , {"hero" : GraphQLField (hero_type , resolve = lambda _obj , _info : hero )}
105
- )
106
-
107
- schema = GraphQLSchema (query )
89
+ @staticmethod
90
+ async def friends (_info ) -> AsyncGenerator [Friend , None ]:
91
+ """A slow async generator yielding the first friend."""
92
+ await sleep (0 )
93
+ yield friends [0 ]
108
94
109
95
110
96
async def complete (document : DocumentNode , root_value : Any = None ) -> Any :
111
- result = experimental_execute_incrementally (schema , document , root_value )
97
+ result = experimental_execute_incrementally (
98
+ schema , document , root_value or {"hero" : hero }
99
+ )
112
100
if is_awaitable (result ):
113
101
result = await result
114
102
@@ -485,24 +473,24 @@ async def can_defer_fragments_with_errors_on_the_top_level_query_field():
485
473
}
486
474
fragment QueryFragment on Query {
487
475
hero {
488
- errorField
476
+ name
489
477
}
490
478
}
491
479
"""
492
480
)
493
- result = await complete (document )
481
+ result = await complete (document , { "hero" : { ** hero , "name" : Resolvers . bad }} )
494
482
495
483
assert result == [
496
484
{"data" : {}, "hasNext" : True },
497
485
{
498
486
"incremental" : [
499
487
{
500
- "data" : {"hero" : {"errorField " : None }},
488
+ "data" : {"hero" : {"name " : None }},
501
489
"errors" : [
502
490
{
503
491
"message" : "bad" ,
504
492
"locations" : [{"column" : 17 , "line" : 7 }],
10000
td>505
- "path" : ["hero" , "errorField " ],
493
+ "path" : ["hero" , "name " ],
506
494
}
507
495
],
508
496
"path" : [],
@@ -666,24 +654,24 @@ async def handles_errors_thrown_in_deferred_fragments():
666
654
}
667
655
}
668
656
fragment NameFragment on Hero {
669
- errorField
657
+ name
670
658
}
671
659
"""
672
660
)
673
- result = await complete (document )
661
+ result = await complete (document , { "hero" : { ** hero , "name" : Resolvers . bad }} )
674
662
675
663
assert result == [
676
664
{"data" : {"hero" : {"id" : "1" }}, "hasNext" : True },
677
665
{
678
666
"incremental" : [
679
667
{
680
- "data" : {"errorField " : None },
668
+ "data" : {"name " : None },
681
669
"path" : ["hero" ],
682
670
"errors" : [
683
671
{
684
672
"message" : "bad" ,
685
673
"locations" : [{"line" : 9 , "column" : 15 }],
686
- "path" : ["hero" , "errorField " ],
674
+ "path" : ["hero" , "name " ],
687
675
}
688
676
],
689
677
},
@@ -703,11 +691,13 @@ async def handles_non_nullable_errors_thrown_in_deferred_fragments():
703
691
}
704
692
}
705
693
fragment NameFragment on Hero {
706
- nonNullErrorField
694
+ nonNullName
707
695
}
708
696
"""
709
697
)
710
- result = await complete (document )
698
+ result = await complete (
699
+ document , {"hero" : {** hero , "nonNullName" : Resolvers .
F42D
null }}
700
+ )
711
701
712
702
assert result == [
713
703
{"data" : {"hero" : {"id" : "1" }}, "hasNext" : True },
@@ -719,9 +709,9 @@ async def handles_non_nullable_errors_thrown_in_deferred_fragments():
719
709
"errors" : [
720
710
{
721
711
"message" : "Cannot return null for non-nullable field"
722
- " Hero.nonNullErrorField ." ,
712
+ " Hero.nonNullName ." ,
723
713
"locations" : [{"line" : 9 , "column" : 15 }],
724
- "path" : ["hero" , "nonNullErrorField " ],
714
+ "path" : ["hero" , "nonNullName " ],
725
715
}
726
716
],
727
717
},
@@ -736,7 +726,7 @@ async def handles_non_nullable_errors_thrown_outside_deferred_fragments():
736
726
"""
737
727
query HeroNameQuery {
738
728
hero {
739
- nonNullErrorField
729
+ nonNullName
740
730
...NameFragment @defer
741
731
}
742
732
}
@@ -745,16 +735,18 @@ async def handles_non_nullable_errors_thrown_outside_deferred_fragments():
745
735
}
746
736
"""
747
737
)
748
- result = await complete (document )
738
+ result = await complete (
739
+ document , {"hero" : {** hero , "nonNullName" : Resolvers .null }}
740
+ )
749
741
750
742
assert result == {
751
743
"data" : {"hero" : None },
752
744
"errors" : [
753
745
{
754
746
"message" : "Cannot return null for non-nullable field"
755
- " Hero.nonNullErrorField ." ,
747
+ " Hero.nonNullName ." ,
756
748
"locations" : [{"line" : 4 , "column" : 17 }],
757
- "path" : ["hero" , "nonNullErrorField " ],
749
+ "path" : ["hero" , "nonNullName " ],
758
750
}
759
751
],
760
752
}
@@ -770,11 +762,13 @@ async def handles_async_non_nullable_errors_thrown_in_deferred_fragments():
770
762
}
771
763
}
772
764
fragment NameFragment on Hero {
773
- asyncNonNullErrorField
765
+ nonNullName
774
766
}
775
767
"""
776
768
)
777
- result = await complete (document )
769
+ result = await complete (
770
+ document , {"hero" : {** hero , "nonNullName" : Resolvers .null_async }}
771
+ )
778
772
779
773
assert result == [
780
774
{"data" : {"hero" : {"id" : "1" }}, "hasNext" : True },
@@ -786,9 +780,9 @@ async def handles_async_non_nullable_errors_thrown_in_deferred_fragments():
786
780
"errors" : [
787
781
{
788
782
"message" : "Cannot return null for non-nullable field"
789
- " Hero.asyncNonNullErrorField ." ,
783
+ " Hero.nonNullName ." ,
790
784
"locations" : [{"line" : 9 , "column" : 15 }],
791
- "path" : ["hero" , "asyncNonNullErrorField " ],
785
+ "path" : ["hero" , "nonNullName " ],
792
786
}
793
787
],
794
788
},
@@ -808,7 +802,7 @@ async def returns_payloads_in_correct_order():
808
802
}
809
803
}
810
804
fragment NameFragment on Hero {
811
- slowField
805
+ name
812
806
friends {
813
807
...NestedFragment @defer
814
808
}
@@ -818,14 +812,14 @@ async def returns_payloads_in_correct_order():
818
812
}
819
813
"""
820
814
)
821
- result = await complete (document )
815
+ result = await complete (document , { "hero" : { ** hero , "name" : Resolvers . slow }} )
822
816
823
817
assert result == [
824
818
{"data" : {"hero" : {"id" : "1" }}, "hasNext" : True },
825
819
{
826
820
"incremental" : [
827
821
{
828
- "data" : {"slowField " : "slow" , "friends" : [{}, {}, {}]},
822
+ "data" : {"name " : "slow" , "friends" : [{}, {}, {}]},
829
823
"path" : ["hero" ],
830
824
}
831
825
],
@@ -909,8 +903,8 @@ async def filters_deferred_payloads_when_list_item_from_async_iterable_nulled():
909
903
"""
910
904
query {
911
905
hero {
912
- asyncFriends {
913
- asyncNonNullErrorField
906
+ friends {
907
+ nonNullName
914
908
...NameFragment @defer
915
909
}
916
910
}
@@ -921,16 +915,18 @@ async def filters_deferred_payloads_when_list_item_from_async_iterable_nulled():
921
915
"""
922
916
)
923
917
924
- result = await complete (document )
918
+ result = await complete (
919
+ document , {"hero" : {** hero , "friends" : Resolvers .friends }}
920
+ )
925
921
926
922
assert result == {
927
- "data" : {"hero" : {"asyncFriends " : [None ]}},
923
+ "data" : {"hero" : {"friends " : [None ]}},
928
924
"errors" : [
929
925
{
930
926
"message" : "Cannot return null for non-nullable field"
931
- " Friend.asyncNonNullErrorField ." ,
927
+ " Friend.nonNullName ." ,
932
928
"locations" : [{"line" : 5 , "column" : 19 }],
933
- "path" : ["hero" , "asyncFriends " , 0 , "asyncNonNullErrorField " ],
929
+ "path" : ["hero" , "friends " , 0 , "nonNullName " ],
934
930
}
935
931
],
936
932
}
@@ -958,14 +954,15 @@ async def original_execute_function_throws_error_if_deferred_and_not_all_is_sync
958
954
document = parse (
959
955
"""
960
956
query Deferred {
961
- hero { slowField }
957
+ hero { name }
962
958
... @defer { hero { id } }
963
959
}
964
960
"""
965
961
)
966
962
963
+ root_value = {"hero" : {** hero , "name" : Resolvers .slow }}
967
964
with pytest .raises (GraphQLError ) as exc_info :
968
- await execute (schema , document , {} ) # type: ignore
965
+ await execute (schema , document , root_value ) # type: ignore
969
966
970
967
assert str (exc_info .value ) == (
971
968
"Executing this GraphQL operation would unexpectedly produce"
0 commit comments