def test_get_schema_with_macros_original_schema_unchanged(self) -> None:
     empty_macro_registry = get_empty_test_macro_registry()
     original_printed_schema = print_schema(
         self.macro_registry.schema_without_macros)
     printed_schema_with_0_macros = print_schema(
         get_schema_with_macros(empty_macro_registry))
     printed_schema_afterwards = print_schema(
         self.macro_registry.schema_without_macros)
     self.assertEqual(original_printed_schema, printed_schema_afterwards)
     self.assertEqual(original_printed_schema, printed_schema_with_0_macros)
        def _get_directives_in_string_form(directives):
            """Return a set of directives in their string form, from the native directive type."""
            fake_query_type = GraphQLObjectType(
                "Query", fields={"foo": GraphQLField(GraphQLString)})
            fake_schema = GraphQLSchema(fake_query_type, directives=directives)

            # Split schema on double line breaks where the following character is not a space.
            # It is not possible to simply split on double line breaks because print_schema puts a
            # double line break between GraphQLArguments. The not space character is retained and
            # reattached to the rest of the line.
            split_schema_lines = [
                line.strip()
                for line in re.split("\n\n([^ ])", print_schema(fake_schema))
            ]

            # Reattach the delimiter's character to the rest of the line. The first line does
            # not have a separated character from regular expression splitting.
            schema_lines = [split_schema_lines[0]] + [
                delimiter_character + line for delimiter_character, line in
                zip(split_schema_lines[1::2], split_schema_lines[2::2])
            ]

            return {
                line
                for line in schema_lines if line.startswith("directive")
            }
 def test_snapshot_graphql_schema_from_orientdb_schema(self):
     class_to_field_type_overrides: Dict[str, Dict[str, GraphQLScalarType]] = {
         "UniquelyIdentifiable": {"uuid": GraphQLID}
     }
     schema, _ = generate_schema(
         self.orientdb_client,  # type: ignore  # from fixture
         class_to_field_type_overrides=class_to_field_type_overrides,
         hidden_classes={ORIENTDB_BASE_VERTEX_CLASS_NAME},
     )
     compare_ignoring_whitespace(self, SCHEMA_TEXT, print_schema(schema), None)
    def test_meta_fields_from_constant(self):
        fields = schema.EXTENDED_META_FIELD_DEFINITIONS.copy()
        fields.update(
            OrderedDict((
                ("foo", GraphQLField(GraphQLString)),
                ("bar", GraphQLField(GraphQLInt)),
            )))
        graphql_type = GraphQLObjectType("MyType", fields)
        custom_schema = GraphQLSchema(graphql_type,
                                      directives=schema.DIRECTIVES)

        # Ensure that stringifying and parsing this schema works just fine.
        printed_schema = print_schema(custom_schema)
        expected_type_definition = """\
type MyType {
    _x_count: Int
    foo: String
    bar: Int
}""".replace("    ", "  ")  # 2 space indentation instead of 4 spaces
        self.assertIn(expected_type_definition, printed_schema)
Esempio n. 5
0
 def __repr__(self):
     return print_schema(self)
Esempio n. 6
0
def get_schema_with_macros(macro_registry):
    """Get a new GraphQLSchema with fields where macro edges can be used.

    Preconditions:
    1. No macro in the registry has the same name as a field on the vertex where it applies.
    2. Members of a union type do not have outgoing macros with the same name.

    An easy way to satisfy the preconditions is to create the macro_registry using
    create_macro_registry, and only update it with register_macro_edge, which does all
    the necessary validation.

    Postconditions:
    1. Every GraphQLQuery that uses macros from this registry appropriately should
       successfully type-check against the schema generated from this function.
    2. A GraphQLQuery that uses macros not present in the registry, or uses valid
       macros but on types they are not defined at should fail schema validation with
       the schema generated from this function.
    3. This function is total -- A valid macro registry should not fail to create a
       GraphQL schema with macros.

    Args:
        macro_registry: MacroRegistry object containing a schema and macro descriptors
                        we want to add to the schema.

    Returns:
        GraphQLSchema with additional fields where macro edges can be used.
    """
    # The easiest way to manipulate the schema is through its AST. The easiest
    # way to get an AST is to print it and parse it.
    schema_ast = parse(print_schema(macro_registry.schema_without_macros))

    fields_by_definition_name = {}
    for definition in schema_ast.definitions:
        if isinstance(definition, (ObjectTypeDefinitionNode, InterfaceTypeDefinitionNode)):
            # Cast to list (from FrozenList) to allow for updates.
            fields_by_definition_name[definition.name.value] = list(definition.fields)

    for class_name, macros_for_class in six.iteritems(macro_registry.macro_edges_at_class):
        for macro_edge_name, macro_edge_descriptor in six.iteritems(macros_for_class):
            list_type_at_target = ListTypeNode(
                type=NamedTypeNode(name=NameNode(value=macro_edge_descriptor.target_class_name))
            )
            arguments = []
            directives = [DirectiveNode(name=NameNode(value=MacroEdgeDirective.name))]
            fields_by_definition_name[class_name].append(
                FieldDefinitionNode(
                    name=NameNode(value=macro_edge_name),
                    arguments=arguments,
                    type=list_type_at_target,
                    directives=directives,
                )
            )

    new_definitions = []
    for definition in schema_ast.definitions:
        # Create new (Object)/(Interface)TypeDefinitionNode based on the updated fields.
        if isinstance(definition, ObjectTypeDefinitionNode):
            new_definitions.append(
                ObjectTypeDefinitionNode(
                    interfaces=definition.interfaces,
                    description=definition.description,
                    name=definition.name,
                    directives=definition.directives,
                    loc=definition.loc,
                    fields=FrozenList(fields_by_definition_name[definition.name.value]),
                )
            )
        elif isinstance(definition, InterfaceTypeDefinitionNode):
            new_definitions.append(
                InterfaceTypeDefinitionNode(
                    description=definition.description,
                    name=definition.name,
                    directives=definition.directives,
                    loc=definition.loc,
                    fields=FrozenList(fields_by_definition_name[definition.name.value]),
                )
            )
        else:
            new_definitions.append(definition)

    new_schema_ast = DocumentNode(definitions=new_definitions)
    return build_ast_schema(new_schema_ast)