|
| 1 | +from ..executor import execute |
| 2 | +from graphql.language.parser import parse |
| 3 | +from graphql.type import (GraphQLArgument, GraphQLField, GraphQLInt, |
| 4 | + GraphQLList, GraphQLObjectType, GraphQLSchema, |
| 5 | + GraphQLString) |
| 6 | + |
| 7 | + |
| 8 | +class NumberHolder(object): |
| 9 | + |
| 10 | + def __init__(self, n): |
| 11 | + self.theNumber = n |
| 12 | + |
| 13 | + |
| 14 | +class Root(object): |
| 15 | + |
| 16 | + def __init__(self, n): |
| 17 | + self.numberHolder = NumberHolder(n) |
| 18 | + |
| 19 | + def immediately_change_the_number(self, n): |
| 20 | + self.numberHolder.theNumber = n |
| 21 | + return self.numberHolder |
| 22 | + |
| 23 | + def promise_to_change_the_number(self, n): |
| 24 | + # TODO: async |
| 25 | + return self.immediately_change_the_number(n) |
| 26 | + |
| 27 | + def fail_to_change_the_number(self, n): |
| 28 | + raise Exception('Cannot change the number') |
| 29 | + |
| 30 | + def promise_and_fail_to_change_the_number(self, n): |
| 31 | + # TODO: async |
| 32 | + self.fail_to_change_the_number(n) |
| 33 | + |
| 34 | + |
| 35 | +NumberHolderType = GraphQLObjectType('NumberHolder', { |
| 36 | + 'theNumber': GraphQLField(GraphQLInt) |
| 37 | +}) |
| 38 | + |
| 39 | +QueryType = GraphQLObjectType('Query', { |
| 40 | + 'numberHolder': GraphQLField(NumberHolderType) |
| 41 | +}) |
| 42 | + |
| 43 | +MutationType = GraphQLObjectType('Mutation', { |
| 44 | + 'immediatelyChangeTheNumber': GraphQLField( |
| 45 | + NumberHolderType, |
| 46 | + args={'newNumber': GraphQLArgument(GraphQLInt)}, |
| 47 | + resolver=lambda obj, args, *_: |
| 48 | + obj.immediately_change_the_number(args['newNumber'])), |
| 49 | + 'promiseToChangeTheNumber': GraphQLField( |
| 50 | + NumberHolderType, |
| 51 | + args={'newNumber': GraphQLArgument(GraphQLInt)}, |
| 52 | + resolver=lambda obj, args, *_: |
| 53 | + obj.promise_to_change_the_number(args['newNumber'])), |
| 54 | + 'failToChangeTheNumber': GraphQLField( |
| 55 | + NumberHolderType, |
| 56 | + args={'newNumber': GraphQLArgument(GraphQLInt)}, |
| 57 | + resolver=lambda obj, args, *_: |
| 58 | + obj.fail_to_change_the_number(args['newNumber'])), |
| 59 | + 'promiseAndFailToChangeTheNumber': GraphQLField( |
| 60 | + NumberHolderType, |
| 61 | + args={'newNumber': GraphQLArgument(GraphQLInt)}, |
| 62 | + resolver=lambda obj, args, *_: |
| 63 | + obj.promise_and_fail_to_change_the_number(args['newNumber'])), |
| 64 | +}) |
| 65 | + |
| 66 | +schema = GraphQLSchema(QueryType, MutationType) |
| 67 | + |
| 68 | + |
| 69 | +def assert_evaluate_mutations_serially(executor=None): |
| 70 | + doc = '''mutation M { |
| 71 | + first: immediatelyChangeTheNumber(newNumber: 1) { |
| 72 | + theNumber |
| 73 | + }, |
| 74 | + second: promiseToChangeTheNumber(newNumber: 2) { |
| 75 | + theNumber |
| 76 | + }, |
| 77 | + third: immediatelyChangeTheNumber(newNumber: 3) { |
| 78 | + theNumber |
| 79 | + } |
| 80 | + fourth: promiseToChangeTheNumber(newNumber: 4) { |
| 81 | + theNumber |
| 82 | + }, |
| 83 | + fifth: immediatelyChangeTheNumber(newNumber: 5) { |
| 84 | + theNumber |
| 85 | + } |
| 86 | + }''' |
| 87 | + ast = parse(doc) |
| 88 | + result = execute(schema, ast, Root(6), operation_name='M', executor=executor) |
| 89 | + assert not result.errors |
| 90 | + assert result.data == \ |
| 91 | + { |
| 92 | + 'first': {'theNumber': 1}, |
| 93 | + 'second': {'theNumber': 2}, |
| 94 | + 'third': {'theNumber': 3}, |
| 95 | + 'fourth': {'theNumber': 4}, |
| 96 | + 'fifth': {'theNumber': 5}, |
| 97 | + } |
| 98 | + |
| 99 | + |
| 100 | +def test_evaluates_mutations_serially(): |
| 101 | + assert_evaluate_mutations_serially() |
| 102 | + |
| 103 | + |
| 104 | +def test_evaluates_mutations_correctly_in_the_presense_of_a_failed_mutation(): |
| 105 | + doc = '''mutation M { |
| 106 | + first: immediatelyChangeTheNumber(newNumber: 1) { |
| 107 | + theNumber |
| 108 | + }, |
| 109 | + second: promiseToChangeTheNumber(newNumber: 2) { |
| 110 | + theNumber |
| 111 | + }, |
| 112 | + third: failToChangeTheNumber(newNumber: 3) { |
| 113 | + theNumber |
| 114 | + } |
| 115 | + fourth: promiseToChangeTheNumber(newNumber: 4) { |
| 116 | + theNumber |
| 117 | + }, |
| 118 | + fifth: immediatelyChangeTheNumber(newNumber: 5) { |
| 119 | + theNumber |
| 120 | + } |
| 121 | + sixth: promiseAndFailToChangeTheNumber(newNumber: 6) { |
| 122 | + theNumber |
| 123 | + } |
| 124 | + }''' |
| 125 | + ast = parse(doc) |
| 126 | + result = execute(schema, ast, Root(6), operation_name='M') |
| 127 | + assert result.data == \ |
| 128 | + { |
| 129 | + 'first': {'theNumber': 1}, |
| 130 | + 'second': {'theNumber': 2}, |
| 131 | + 'third': None, |
| 132 | + 'fourth': {'theNumber': 4}, |
| 133 | + 'fifth': {'theNumber': 5}, |
| 134 | + 'sixth': None, |
| 135 | + } |
| 136 | + assert len(result.errors) == 2 |
| 137 | + # TODO: check error location |
| 138 | + assert result.errors[0].message == 'Cannot change the number' |
| 139 | + assert result.errors[1].message == 'Cannot change the number' |
0 commit comments