예제 #1
0
        public ScalarFieldTypeDescription GetCustomScalarFieldType(GraphQlGeneratorConfiguration configuration,
                                                                   GraphQlType baseType,
                                                                   GraphQlTypeBase valueType,
                                                                   string valueName)
        {
            valueType = valueType is GraphQlFieldType fieldType?fieldType.UnwrapIfNonNull() : valueType;

            // DateTime and Byte
            switch (valueType.Name)
            {
            case "Uuid": return(new ScalarFieldTypeDescription {
                    NetTypeName = "Guid?", FormatMask = "N"
                });

            case "Uuid!": return(new ScalarFieldTypeDescription {
                    NetTypeName = "Guid", FormatMask = "N"
                });

            case "Long": return(new ScalarFieldTypeDescription {
                    NetTypeName = "long?", FormatMask = null
                });

            case "DateTime": return(new ScalarFieldTypeDescription {
                    NetTypeName = "DateTime?", FormatMask = null
                });

            case "DateTime!": return(new ScalarFieldTypeDescription {
                    NetTypeName = "DateTime", FormatMask = null
                });
            }

            // fallback - not needed if all fields and arguments are resolved or the expected type is of "object" type
            return(DefaultScalarFieldTypeMappingProvider.Instance.GetCustomScalarFieldType(configuration, baseType, valueType, valueName));
        }
            public ScalarFieldTypeDescription GetCustomScalarFieldType(GraphQlGeneratorConfiguration configuration, GraphQlType baseType, GraphQlTypeBase valueType, string valueName)
            {
                var isNotNull     = valueType.Kind == GraphQlTypeKind.NonNull;
                var unwrappedType = valueType is GraphQlFieldType fieldType?fieldType.UnwrapIfNonNull() : valueType;

                var nullablePostfix = isNotNull ? null : "?";

                if (unwrappedType.Name == "ID")
                {
                    return new ScalarFieldTypeDescription {
                               NetTypeName = "Guid" + nullablePostfix, FormatMask = "N"
                    }
                }
                ;

                if (valueName == "before" || valueName == "after" || unwrappedType.Name == "DateTimeOffset")
                {
                    return new ScalarFieldTypeDescription {
                               NetTypeName = "DateTimeOffset" + nullablePostfix, FormatMask = "yyyy-MM-dd\"T\"HH:mm"
                    }
                }
                ;

                return(DefaultScalarFieldTypeMappingProvider.Instance.GetCustomScalarFieldType(configuration, baseType, valueType, valueName));
            }
        }
        public void NewCSharpSyntaxWithClassPrefixAndSuffix()
        {
            var configuration =
                new GraphQlGeneratorConfiguration
            {
                CSharpVersion       = CSharpVersion.Newest,
                ClassPrefix         = "Test",
                ClassSuffix         = "V1",
                MemberAccessibility = MemberAccessibility.Internal
            };

            var schema = DeserializeTestSchema("TestSchema2");

            var stringBuilder = new StringBuilder();
            var generator     = new GraphQlGenerator(configuration);

            generator.Generate(CreateGenerationContext(stringBuilder, schema));

            var generatedSourceCode = StripBaseClasses(stringBuilder.ToString());
            var expectedOutput      = GetTestResource("ExpectedNewCSharpSyntaxWithClassPrefixAndSuffix");

            generatedSourceCode.ShouldBe(expectedOutput);

            CompileIntoAssembly(stringBuilder.ToString(), "GraphQLTestAssembly");

            Type.GetType("GraphQLTestAssembly.GraphQlQueryBuilder, GraphQLTestAssembly").ShouldNotBeNull();
        }
        public static async Task <IReadOnlyCollection <FileInfo> > GenerateClientSourceCode(ProgramOptions options)
        {
            var schema = await GraphQlGenerator.RetrieveSchema(options.ServiceUrl, options.Authorization);

            var generatorConfiguration =
                new GraphQlGeneratorConfiguration
            {
                CSharpVersion          = options.CSharpVersion,
                ClassPostfix           = options.ClassPostfix,
                GeneratePartialClasses = options.PartialClasses,
                MemberAccessibility    = options.MemberAccessibility,
                IdTypeMapping          = options.IdTypeMapping
            };

            var generator = new GraphQlGenerator(generatorConfiguration);

            if (options.OutputType == OutputType.SingleFile)
            {
                await File.WriteAllTextAsync(options.OutputPath, generator.GenerateFullClientCSharpFile(schema, options.Namespace));

                return(new[] { new FileInfo(options.OutputPath) });
            }

            var multipleFileGenerationContext = new MultipleFileGenerationContext(schema, options.OutputPath, options.Namespace);

            generator.Generate(multipleFileGenerationContext);
            return(multipleFileGenerationContext.Files);
        }
예제 #5
0
        public void GenerateDataClassesWithTypeConfiguration()
        {
            var configuration =
                new GraphQlGeneratorConfiguration
            {
                IntegerTypeMapping     = IntegerTypeMapping.Int64,
                FloatTypeMapping       = FloatTypeMapping.Double,
                BooleanTypeMapping     = BooleanTypeMapping.Custom,
                IdTypeMapping          = IdTypeMapping.String,
                GeneratePartialClasses = false,
                PropertyGeneration     = PropertyGenerationOption.BackingField
            };

            configuration.CustomScalarFieldTypeMapping =
                (baseType, valueType, valueName) =>
                valueType.Name == "Boolean"
                        ? new ScalarFieldTypeDescription {
                NetTypeName = "bool"
            }
                        : configuration.DefaultScalarFieldTypeMapping(baseType, valueType, valueName);

            var stringBuilder = new StringBuilder();

            new GraphQlGenerator(configuration).Generate(CreateGenerationContext(stringBuilder, TestSchema, GeneratedObjectType.DataClasses));

            var expectedDataClasses = GetTestResource("ExpectedDataClassesWithTypeConfiguration");

            stringBuilder.ToString().ShouldBe(expectedDataClasses);
        }
            public ScalarFieldTypeDescription GetCustomScalarFieldType(GraphQlGeneratorConfiguration configuration, GraphQlType baseType, GraphQlTypeBase valueType, string valueName) =>
            valueType.Name == "Boolean"
                    ? new ScalarFieldTypeDescription
            {
                NetTypeName = "bool"
            }

                    : DefaultScalarFieldTypeMappingProvider.Instance.GetCustomScalarFieldType(configuration, baseType, valueType, valueName);
        private static async Task GenerateClientSourceCode(ProgramOptions options, List <FileInfo> generatedFiles)
        {
            GraphQlSchema schema;

            if (String.IsNullOrWhiteSpace(options.ServiceUrl))
            {
                schema = GraphQlGenerator.DeserializeGraphQlSchema(await File.ReadAllTextAsync(options.SchemaFileName));
            }
            else
            {
                if (!KeyValueParameterParser.TryGetCustomHeaders(options.Header, out var headers, out var headerParsingErrorMessage))
                {
                    throw new InvalidOperationException(headerParsingErrorMessage);
                }

                schema = await GraphQlGenerator.RetrieveSchema(new HttpMethod(options.HttpMethod), options.ServiceUrl, headers);
            }

            var generatorConfiguration =
                new GraphQlGeneratorConfiguration
            {
                CSharpVersion          = options.CSharpVersion,
                ClassPrefix            = options.ClassPrefix,
                ClassSuffix            = options.ClassSuffix,
                GeneratePartialClasses = options.PartialClasses,
                MemberAccessibility    = options.MemberAccessibility,
                IdTypeMapping          = options.IdTypeMapping,
                FloatTypeMapping       = options.FloatTypeMapping,
                JsonPropertyGeneration = options.JsonPropertyAttribute
            };

            if (!KeyValueParameterParser.TryGetCustomClassMapping(options.ClassMapping, out var customMapping, out var customMappingParsingErrorMessage))
            {
                throw new InvalidOperationException(customMappingParsingErrorMessage);
            }

            foreach (var kvp in customMapping)
            {
                generatorConfiguration.CustomClassNameMapping.Add(kvp);
            }

            var generator = new GraphQlGenerator(generatorConfiguration);

            if (options.OutputType == OutputType.SingleFile)
            {
                await File.WriteAllTextAsync(options.OutputPath, generator.GenerateFullClientCSharpFile(schema, options.Namespace));

                generatedFiles.Add(new FileInfo(options.OutputPath));
            }
            else
            {
                var multipleFileGenerationContext = new MultipleFileGenerationContext(schema, options.OutputPath, options.Namespace);
                generator.Generate(multipleFileGenerationContext);
                generatedFiles.AddRange(multipleFileGenerationContext.Files);
            }
        }
        public void GenerateDataClasses()
        {
            var configuration = new GraphQlGeneratorConfiguration();

            configuration.CustomClassNameMapping.Add("AwayMode", "VacationMode");

            var stringBuilder = new StringBuilder();

            new GraphQlGenerator(configuration).Generate(CreateGenerationContext(stringBuilder, TestSchema, GeneratedObjectType.DataClasses));
            var expectedDataClasses = GetTestResource("ExpectedDataClasses");

            stringBuilder.ToString().ShouldBe(expectedDataClasses);
        }
        public void GenerateFullClientCSharpFile()
        {
            var configuration =
                new GraphQlGeneratorConfiguration
            {
                CommentGeneration = CommentGenerationOption.CodeSummary | CommentGenerationOption.DescriptionAttribute
            };

            var generator           = new GraphQlGenerator(configuration);
            var generatedSourceCode = generator.GenerateFullClientCSharpFile(TestSchema, "GraphQlGenerator.Test");
            var expectedOutput      = GetTestResource("ExpectedFullClientCSharpFile");

            generatedSourceCode.ShouldBe(expectedOutput);
        }
        public void GenerateQueryBuilder()
        {
            var configuration = new GraphQlGeneratorConfiguration();

            configuration.CustomClassNameMapping.Add("AwayMode", "VacationMode");

            var stringBuilder = new StringBuilder();

            new GraphQlGenerator(configuration).Generate(CreateGenerationContext(stringBuilder, TestSchema, GeneratedObjectType.QueryBuilders));

            var expectedQueryBuilders = GetTestResource("ExpectedQueryBuilders");
            var generatedSourceCode   = StripBaseClasses(stringBuilder.ToString());

            generatedSourceCode.ShouldBe(expectedQueryBuilders);
        }
예제 #11
0
        public ScalarFieldTypeDescription GetCustomScalarFieldType(GraphQlGeneratorConfiguration configuration, GraphQlType baseType, GraphQlTypeBase valueType, string valueName)
        {
            valueName = NamingHelper.ToPascalCase(valueName);

            if (valueName == "From" || valueName == "ValidFrom" || valueName == "To" || valueName == "ValidTo" ||
                valueName == "CreatedAt" || valueName == "UpdatedAt" || valueName == "ModifiedAt" || valueName == "DeletedAt" ||
                valueName.EndsWith("Timestamp"))
            {
                return new ScalarFieldTypeDescription {
                           NetTypeName = "DateTimeOffset?"
                }
            }
            ;

            return(GetFallbackFieldType(configuration, valueType));
        }
예제 #12
0
        public void GenerateFormatMasks()
        {
            var configuration =
                new GraphQlGeneratorConfiguration
            {
                IdTypeMapping = IdTypeMapping.Custom
            };

            configuration.CustomScalarFieldTypeMapping =
                (baseType, valueType, valueName) =>
            {
                var isNotNull     = valueType.Kind == GraphQlTypeKind.NonNull;
                var unwrappedType = valueType is GraphQlFieldType fieldType?fieldType.UnwrapIfNonNull() : valueType;

                var nullablePostfix = isNotNull ? "?" : null;

                if (unwrappedType.Name == "ID")
                {
                    return new ScalarFieldTypeDescription {
                               NetTypeName = "Guid" + nullablePostfix, FormatMask = "N"
                    }
                }
                ;

                if (valueName == "before" || valueName == "after")
                {
                    return new ScalarFieldTypeDescription {
                               NetTypeName = "DateTimeOffset" + nullablePostfix, FormatMask = "yyyy-MM-dd\"T\"HH:mm"
                    }
                }
                ;

                return(configuration.DefaultScalarFieldTypeMapping(baseType, valueType, valueName));
            };

            var stringBuilder = new StringBuilder();
            var generator     = new GraphQlGenerator(configuration);
            var schema        = DeserializeTestSchema("TestSchema3");

            generator.Generate(CreateGenerationContext(stringBuilder, schema));

            var expectedDataClasses = GetTestResource("ExpectedFormatMasks");
            var generatedSourceCode = StripBaseClasses(stringBuilder.ToString());

            generatedSourceCode.ShouldBe(expectedDataClasses);
        }
예제 #13
0
        public async Task RunAsync()
        {
            var config = new GraphQlGeneratorConfiguration()
            {
                IncludeDeprecatedFields = options.GenerateDeprecatedTypes,
                JsonPropertyGeneration  = options.JsonPropertyGeneration,
                CSharpVersion           = options.UseNullable ? CSharpVersion.NewestWithNullableReferences : CSharpVersion.Compatible
            };

            var schema = await SchemaConverter.ReadAsync(options.Source).ConfigureAwait(false);

            var generator = new GraphQlGenerator(config);
            var content   = generator.GenerateFullClientCSharpFile(schema, options.Namespace);

            Console.WriteLine($"writing client-code to {options.DestinationFile}");
            File.WriteAllText(options.DestinationFile, content);
        }
        public void WithNullableReferences()
        {
            var configuration = new GraphQlGeneratorConfiguration {
                CSharpVersion = CSharpVersion.NewestWithNullableReferences
            };
            var schema = DeserializeTestSchema("TestSchema2");

            var stringBuilder = new StringBuilder();
            var generator     = new GraphQlGenerator(configuration);

            generator.Generate(CreateGenerationContext(stringBuilder, schema));

            var expectedOutput      = GetTestResource("ExpectedWithNullableReferences");
            var generatedSourceCode = StripBaseClasses(stringBuilder.ToString());

            generatedSourceCode.ShouldBe(expectedOutput);
        }
예제 #15
0
        public async Task GenerateAsync()
        {
            var schema = await GraphQlGenerator.RetrieveSchema("https://*****:*****@"C:\projects\SuSoClient\Repository\src\SurveySolutionsClient\Graphql.cs", csharpCode);
        }
예제 #16
0
        public static ScalarFieldTypeDescription GetFallbackFieldType(GraphQlGeneratorConfiguration configuration, GraphQlTypeBase valueType)
        {
            valueType = (valueType as GraphQlFieldType)?.UnwrapIfNonNull() ?? valueType;
            if (valueType.Kind == GraphQlTypeKind.Enum)
            {
                return new ScalarFieldTypeDescription {
                           NetTypeName = configuration.ClassPrefix + NamingHelper.ToPascalCase(valueType.Name) + configuration.ClassSuffix + "?"
                }
            }
            ;

            var dataType = valueType.Name == GraphQlTypeBase.GraphQlTypeScalarString ? "string" : "object";

            return(new ScalarFieldTypeDescription {
                NetTypeName = GraphQlGenerator.AddQuestionMarkIfNullableReferencesEnabled(configuration, dataType)
            });
        }
    }
        public void DeprecatedAttributes()
        {
            var configuration =
                new GraphQlGeneratorConfiguration
            {
                CSharpVersion           = CSharpVersion.Newest,
                CommentGeneration       = CommentGenerationOption.CodeSummary | CommentGenerationOption.DescriptionAttribute,
                IncludeDeprecatedFields = true,
                GeneratePartialClasses  = false
            };

            var schema = DeserializeTestSchema("TestSchemaWithDeprecatedFields");

            var stringBuilder = new StringBuilder();

            new GraphQlGenerator(configuration).Generate(CreateGenerationContext(stringBuilder, schema, GeneratedObjectType.DataClasses));
            var expectedOutput = GetTestResource("ExpectedDeprecatedAttributes").Replace("\r", String.Empty);

            stringBuilder.ToString().Replace("\r", String.Empty).ShouldBe(expectedOutput);
        }
        public void GenerateFormatMasks()
        {
            var configuration =
                new GraphQlGeneratorConfiguration
            {
                IdTypeMapping = IdTypeMapping.Custom,
                ScalarFieldTypeMappingProvider = TestFormatMaskScalarFieldTypeMappingProvider.Instance
            };

            var stringBuilder = new StringBuilder();
            var generator     = new GraphQlGenerator(configuration);
            var schema        = DeserializeTestSchema("TestSchema3");

            generator.Generate(CreateGenerationContext(stringBuilder, schema));

            var expectedDataClasses = GetTestResource("ExpectedFormatMasks");
            var generatedSourceCode = StripBaseClasses(stringBuilder.ToString());

            generatedSourceCode.ShouldBe(expectedDataClasses);
        }
    public void GenerateDataClassesWithTypeConfiguration()
    {
        var configuration =
            new GraphQlGeneratorConfiguration
        {
            IntegerTypeMapping             = IntegerTypeMapping.Int64,
            FloatTypeMapping               = FloatTypeMapping.Double,
            BooleanTypeMapping             = BooleanTypeMapping.Custom,
            IdTypeMapping                  = IdTypeMapping.String,
            GeneratePartialClasses         = false,
            PropertyGeneration             = PropertyGenerationOption.BackingField,
            ScalarFieldTypeMappingProvider = new TestCustomBooleanTypeMappingProvider()
        };

        var stringBuilder = new StringBuilder();

        new GraphQlGenerator(configuration).Generate(CreateGenerationContext(stringBuilder, TestSchema, GeneratedObjectType.DataClasses));
        var expectedDataClasses = GetTestResource("ExpectedSingleFileGenerationContext.DataClassesWithTypeConfiguration");

        stringBuilder.ToString().ShouldBe(expectedDataClasses);
    }
        public void WithUnions()
        {
            var configuration =
                new GraphQlGeneratorConfiguration
            {
                CSharpVersion                  = CSharpVersion.NewestWithNullableReferences,
                JsonPropertyGeneration         = JsonPropertyGenerationOption.UseDefaultAlias,
                ScalarFieldTypeMappingProvider = TestFormatMaskScalarFieldTypeMappingProvider.Instance
            };

            var schema = DeserializeTestSchema("TestSchemaWithUnions");

            var stringBuilder = new StringBuilder();
            var generator     = new GraphQlGenerator(configuration);

            generator.Generate(CreateGenerationContext(stringBuilder, schema));

            var expectedOutput      = GetTestResource("ExpectedWithUnions");
            var generatedSourceCode = StripBaseClasses(stringBuilder.ToString());

            generatedSourceCode.ShouldBe(expectedOutput);
        }
        public static async Task GeneratAsync(this GraphqlGeneratorConfig config)
        {
            try
            {
                GraphQlGeneratorConfiguration.CustomScalarFieldTypeMapping =
                    (baseType, valueType, valueName) =>
                {
                    valueType = valueType is GraphQlFieldType fieldType?fieldType.UnwrapIfNonNull() : valueType;

                    return(config.FieldTypeMappings.TryGetValue(valueType.Name, out var overrideTypeName)
                            ? overrideTypeName
                            : GraphQlGeneratorConfiguration.DefaultScalarFieldTypeMapping(baseType, valueType, valueName));
                };


                var httpClient = new HttpClient();

                if (!string.IsNullOrEmpty(config.AuthenticationHeander.Key))
                {
                    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(config.AuthenticationHeander.Key, config.AuthenticationHeander.Value);
                }

                foreach (var header in config.HttpHeaders)
                {
                    httpClient.DefaultRequestHeaders.Add(header.Key, header.Value);
                }

                using var response =
                          await httpClient.PostAsync(config.SchemaUrl,
                                                     new StringContent (JsonConvert.SerializeObject(new { query = IntrospectionQuery.Text }), Encoding.UTF8, "application/json"));

                var schema =
                    response.Content == null
                        ? "(no content)"
                        : await response.Content.ReadAsStringAsync();

                if (!response.IsSuccessStatusCode)
                {
                    throw new InvalidOperationException($"Status code: {(int)response.StatusCode} ({response.StatusCode}); content: {schema}");
                }

                if (config.GenerateSchema)
                {
                    var formattedSchema = JToken.Parse(schema).ToString(Formatting.Indented);
                    using var schemaWriter = File.CreateText(config.DestinationPath + "schema.graphql");
                    await schemaWriter.WriteAsync(formattedSchema);
                }


                var deserializedSchema = GraphQlGenerator.DeserializeGraphQlSchema(schema);

                var builder = new StringBuilder();

                GraphQlGenerator.GenerateQueryBuilder(deserializedSchema, builder);

                builder.AppendLine();
                builder.AppendLine();

                GraphQlGenerator.GenerateDataClasses(deserializedSchema, builder);

                using var writer = File.CreateText(config.DestinationPath + "QueryBuilder.cs");
                writer.WriteLine(RequiredNamespaces);
                writer.WriteLine();

                writer.WriteLine($"namespace {config.Namespace}");
                writer.WriteLine("{");

                var indentedLines =
                    builder
                    .ToString()
                    .Split(new[] { Environment.NewLine }, StringSplitOptions.None)
                    .Select(l => $"    {l}");

                foreach (var line in indentedLines)
                {
                    writer.WriteLine(line);
                }

                writer.WriteLine("}");
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
        public void GeneratedQuery()
        {
            var configuration = new GraphQlGeneratorConfiguration {
                JsonPropertyGeneration = JsonPropertyGenerationOption.Always
            };

            var schema        = DeserializeTestSchema("TestSchema2");
            var stringBuilder = new StringBuilder();
            var generator     = new GraphQlGenerator(configuration);

            generator.Generate(CreateGenerationContext(stringBuilder, schema));

            stringBuilder.AppendLine();
            stringBuilder.AppendLine(
                @"public class TestQueryBuilder : GraphQlQueryBuilder<TestQueryBuilder>
{
    private static readonly FieldMetadata[] AllFieldMetadata =
        new []
        {
            new FieldMetadata { Name = ""testField"" },
            new FieldMetadata { Name = ""objectParameter"" }
        };

    protected override string TypeName { get; } = ""Test"";

    public override IReadOnlyList<FieldMetadata> AllFields { get; } = AllFieldMetadata;

	public TestQueryBuilder WithTestField(
        QueryBuilderParameter<short?> valueInt16 = null,
        QueryBuilderParameter<ushort?> valueUInt16 = null,
        QueryBuilderParameter<byte?> valueByte = null,
        QueryBuilderParameter<int?> valueInt32 = null,
        QueryBuilderParameter<uint?> valueUInt32 = null,
        QueryBuilderParameter<long?> valueInt64 = null,
        QueryBuilderParameter<ulong?> valueUInt64 = null,
        QueryBuilderParameter<float?> valueSingle = null,
        QueryBuilderParameter<double?> valueDouble = null,
        QueryBuilderParameter<decimal?> valueDecimal = null,
        QueryBuilderParameter<DateTime?> valueDateTime = null,
        QueryBuilderParameter<DateTimeOffset?> valueDateTimeOffset = null,
        QueryBuilderParameter<Guid?> valueGuid = null,
        QueryBuilderParameter<string> valueString = null)
	{
		var args = new List<QueryBuilderArgumentInfo>();
		if (valueInt16 != null)
			args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueInt16"", ArgumentValue = valueInt16 });

		if (valueUInt16 != null)
			args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueUInt16"", ArgumentValue = valueUInt16 });

		if (valueByte != null)
			args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueByte"", ArgumentValue = valueByte });

		if (valueInt32 != null)
			args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueInt32"", ArgumentValue = valueInt32 });

		if (valueUInt32 != null)
			args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueUInt32"", ArgumentValue = valueUInt32 });

		if (valueInt64 != null)
			args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueInt64"", ArgumentValue = valueInt64 });

		if (valueUInt64 != null)
			args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueUInt64"", ArgumentValue = valueUInt64 });

		if (valueSingle != null)
			args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueSingle"", ArgumentValue = valueSingle });

		if (valueDouble != null)
			args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueDouble"", ArgumentValue = valueDouble });

		if (valueDecimal != null)
			args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueDecimal"", ArgumentValue = valueDecimal });

		if (valueDateTime != null)
			args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueDateTime"", ArgumentValue = valueDateTime, FormatMask = ""yy-MM-dd HH:mmZ"" });

		if (valueDateTimeOffset != null)
			args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueDateTimeOffset"", ArgumentValue = valueDateTimeOffset });

		if (valueGuid != null)
			args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueGuid"", ArgumentValue = valueGuid });

		if (valueString != null)
			args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""valueString"", ArgumentValue = valueString });

		return WithScalarField(""testField"", null, null, args);
	}

    public TestQueryBuilder WithObjectParameterField(QueryBuilderParameter<object> objectParameter = null)
	{
		var args = new List<QueryBuilderArgumentInfo>();
		if (objectParameter != null)
			args.Add(new QueryBuilderArgumentInfo { ArgumentName = ""objectParameter"", ArgumentValue = objectParameter });

        return WithScalarField(""objectParameter"", ""fieldAlias"", new GraphQlDirective[] { new IncludeDirective(new GraphQlQueryParameter<bool>(""direct"", ""Boolean"", true)), new SkipDirective((QueryBuilderParameter<bool>)false) }, args);
    }

    public TestQueryBuilder WithTestFragment(MeQueryBuilder queryBuilder) => WithFragment(queryBuilder, null);
}");

            const string assemblyName = "GeneratedQueryTestAssembly";

            CompileIntoAssembly(stringBuilder.ToString(), assemblyName);

            var builderType = Type.GetType($"{assemblyName}.TestQueryBuilder, {assemblyName}");

            builderType.ShouldNotBeNull();
            var formattingType = Type.GetType($"{assemblyName}.Formatting, {assemblyName}");

            formattingType.ShouldNotBeNull();

            var builderInstance = Activator.CreateInstance(builderType);

            builderType
            .GetMethod("WithTestField", BindingFlags.Instance | BindingFlags.Public)
            .Invoke(
                builderInstance,
                new object[]
            {
                (short)1,
                (ushort)2,
                (byte)3,
                4,
                (uint)5,
                6L,
                (ulong)7,
                8.123f,
                9.456d,
                10.789m,
                new DateTime(2019, 6, 30, 0, 27, 47, DateTimeKind.Utc).AddTicks(1234567),
                new DateTimeOffset(2019, 6, 30, 2, 27, 47, TimeSpan.FromHours(2)).AddTicks(1234567),
                Guid.Empty,
                "string value"
            }.Select(p => CreateParameter(assemblyName, p)).ToArray());

            builderType
            .GetMethod("WithObjectParameterField", BindingFlags.Instance | BindingFlags.Public)
            .Invoke(
                builderInstance,
                new object[]
            {
                new []
                {
                    JsonConvert.DeserializeObject("{ \"rootProperty1\": \"root value 1\", \"rootProperty2\": 123.456, \"rootProperty3\": true, \"rootProperty4\": null, \"rootProperty5\": { \"nestedProperty\": 987 } }"),
                    JsonConvert.DeserializeObject("[{ \"rootProperty1\": \"root value 2\" }, { \"rootProperty1\": false }]")
                }
            }.Select(p => CreateParameter(assemblyName, p)).ToArray());

            var query =
                builderType
                .GetMethod("Build", BindingFlags.Instance | BindingFlags.Public)
                .Invoke(builderInstance, new [] { Enum.Parse(formattingType, "None"), (byte)2 });

            query.ShouldBe("{testField(valueInt16:1,valueUInt16:2,valueByte:3,valueInt32:4,valueUInt32:5,valueInt64:6,valueUInt64:7,valueSingle:8.123,valueDouble:9.456,valueDecimal:10.789,valueDateTime:\"19-06-30 00:27Z\",valueDateTimeOffset:\"2019-06-30T02:27:47.1234567+02:00\",valueGuid:\"00000000-0000-0000-0000-000000000000\",valueString:\"string value\"),fieldAlias:objectParameter(objectParameter:[{rootProperty1:\"root value 1\",rootProperty2:123.456,rootProperty3:true,rootProperty4:null,rootProperty5:{nestedProperty:987}},[{rootProperty1:\"root value 2\"},{rootProperty1:false}]])@include(if:$direct)@skip(if:false)}");
            query =
                builderType
                .GetMethod("Build", BindingFlags.Instance | BindingFlags.Public)
                .Invoke(builderInstance, new[] { Enum.Parse(formattingType, "Indented"), (byte)2 });

            query.ShouldBe($" {{{Environment.NewLine}  testField(valueInt16: 1, valueUInt16: 2, valueByte: 3, valueInt32: 4, valueUInt32: 5, valueInt64: 6, valueUInt64: 7, valueSingle: 8.123, valueDouble: 9.456, valueDecimal: 10.789, valueDateTime: \"19-06-30 00:27Z\", valueDateTimeOffset: \"2019-06-30T02:27:47.1234567+02:00\", valueGuid: \"00000000-0000-0000-0000-000000000000\", valueString: \"string value\"){Environment.NewLine}  fieldAlias: objectParameter(objectParameter: [{Environment.NewLine}    {{{Environment.NewLine}      rootProperty1: \"root value 1\",{Environment.NewLine}      rootProperty2: 123.456,{Environment.NewLine}      rootProperty3: true,{Environment.NewLine}      rootProperty4: null,{Environment.NewLine}      rootProperty5: {{{Environment.NewLine}        nestedProperty: 987}}}},{Environment.NewLine}    [{Environment.NewLine}    {{{Environment.NewLine}      rootProperty1: \"root value 2\"}},{Environment.NewLine}    {{{Environment.NewLine}      rootProperty1: false}}]]) @include(if: $direct) @skip(if: false){Environment.NewLine}}}");

            var rootQueryBuilderType = Type.GetType($"{assemblyName}.QueryQueryBuilder, {assemblyName}");

            rootQueryBuilderType.ShouldNotBeNull();
            var rootQueryBuilderInstance = rootQueryBuilderType.GetConstructor(new [] { typeof(string) }).Invoke(new object[1]);

            rootQueryBuilderType.GetMethod("WithAllFields", BindingFlags.Instance | BindingFlags.Public).Invoke(rootQueryBuilderInstance, null);
            rootQueryBuilderType
            .GetMethod("Build", BindingFlags.Instance | BindingFlags.Public)
            .Invoke(rootQueryBuilderInstance, new[] { Enum.Parse(formattingType, "None"), (byte)2 });

            builderType
            .GetMethod("Clear", BindingFlags.Instance | BindingFlags.Public)
            .Invoke(builderInstance, null);

            var meBuilderType = Type.GetType($"{assemblyName}.MeQueryBuilder, {assemblyName}");
            var childFragmentBuilderInstance = Activator.CreateInstance(meBuilderType);

            meBuilderType.GetMethod("WithAllScalarFields", BindingFlags.Instance | BindingFlags.Public).Invoke(childFragmentBuilderInstance, null);

            builderType
            .GetMethod("WithTestFragment", BindingFlags.Instance | BindingFlags.Public)
            .Invoke(builderInstance, new [] { childFragmentBuilderInstance });

            query =
                builderType
                .GetMethod("Build", BindingFlags.Instance | BindingFlags.Public)
                .Invoke(builderInstance, new[] { Enum.Parse(formattingType, "None"), (byte)2 });

            query.ShouldBe("{...on Me{id,firstName,lastName,fullName,ssn,email,language,tone,mobile}}");
        }
예제 #23
0
 public override void BeforeGeneration(GraphQlGeneratorConfiguration configuration)
 {
     _enums = _directives = _queryBuilders = _dataClasses = 0;
     base.BeforeGeneration(configuration);
 }
        public void MultipleFileGeneration()
        {
            var configuration =
                new GraphQlGeneratorConfiguration
            {
                CommentGeneration = CommentGenerationOption.CodeSummary | CommentGenerationOption.DescriptionAttribute,
                CSharpVersion     = CSharpVersion.Newest
            };

            var generator = new GraphQlGenerator(configuration);

            var tempPath      = Path.GetTempPath();
            var directoryInfo = Directory.CreateDirectory(Path.Combine(tempPath, "GraphQlGeneratorTest"));

            try
            {
                var context = new MultipleFileGenerationContext(DeserializeTestSchema("TestSchema2"), directoryInfo.FullName, "GraphQlGeneratorTest", "GraphQlGeneratorTest.csproj");
                generator.Generate(context);

                var files     = directoryInfo.GetFiles().OrderBy(f => f.Name).ToArray();
                var fileNames = files.Select(f => f.Name);
                fileNames.ShouldBe(
                    new[]
                {
                    "About.cs",
                    "AboutItem.cs",
                    "AboutItemQueryBuilder.cs",
                    "AboutQueryBuilder.cs",
                    "Address.cs",
                    "AddressQueryBuilder.cs",
                    "AppState.cs",
                    "AppStateFronScreen.cs",
                    "AppStateFronScreenMutation.cs",
                    "AppStateFronScreenQueryBuilder.cs",
                    "AppStateJourney.cs",
                    "AppStateJourneyMutation.cs",
                    "AppStateJourneyQueryBuilder.cs",
                    "AppStateMutation.cs",
                    "AppStateQueryBuilder.cs",
                    "Avatar.cs",
                    "AwayMode.cs",
                    "AwayModeQueryBuilder.cs",
                    "AwayModeSettings.cs",
                    "AwayModeSettingsQueryBuilder.cs",
                    "BaseClasses.cs",
                    "Comparison.cs",
                    "ComparisonData.cs",
                    "ComparisonDataQueryBuilder.cs",
                    "ComparisonQueryBuilder.cs",
                    "Consumption.cs",
                    "ConsumptionMonth.cs",
                    "ConsumptionMonthQueryBuilder.cs",
                    "ConsumptionQueryBuilder.cs",
                    "CreditCard.cs",
                    "CreditCardQueryBuilder.cs",
                    "DayNightSchedule.cs",
                    "DayNightScheduleQueryBuilder.cs",
                    "DayNightScheduleSettings.cs",
                    "DayNightScheduleSettingsQueryBuilder.cs",
                    "Disaggregation.cs",
                    "DisaggregationQueryBuilder.cs",
                    "EnergyDeal.cs",
                    "EnergyDealQueryBuilder.cs",
                    "Feed.cs",
                    "FeedItem.cs",
                    "FeedItemQueryBuilder.cs",
                    "FeedQueryBuilder.cs",
                    "GqlMutationError.cs",
                    "GqlMutationErrorQueryBuilder.cs",
                    "GqlMutationGeneralResponse.cs",
                    "GqlMutationGeneralResponseQueryBuilder.cs",
                    "GraphQlGeneratorTest.csproj",
                    "GraphQlTypes.cs",
                    "Greeting.cs",
                    "GreetingQueryBuilder.cs",
                    "Home.cs",
                    "HomeMutation.cs",
                    "HomeMutationQueryBuilder.cs",
                    "HomeProfileQuestion.cs",
                    "HomeProfileQuestionAnswer.cs",
                    "HomeProfileQuestionInput.cs",
                    "HomeProfileQuestionInputQueryBuilder.cs",
                    "HomeProfileQuestionQueryBuilder.cs",
                    "HomeQueryBuilder.cs",
                    "IncludeDirective.cs",
                    "Invoice.cs",
                    "InvoicePayment.cs",
                    "InvoicePaymentQueryBuilder.cs",
                    "InvoiceQueryBuilder.cs",
                    "InvoiceSection.cs",
                    "InvoiceSectionQueryBuilder.cs",
                    "Me.cs",
                    "MeMutation.cs",
                    "MeMutationQueryBuilder.cs",
                    "MeQueryBuilder.cs",
                    "Mutation.cs",
                    "MutationQueryBuilder.cs",
                    "PairableDevice.cs",
                    "PairableDeviceOAuth.cs",
                    "PairableDeviceOAuthQueryBuilder.cs",
                    "PairableDeviceQueryBuilder.cs",
                    "PairDeviceResult.cs",
                    "PairDeviceResultQueryBuilder.cs",
                    "PaymentMethod.cs",
                    "PaymentMethodQueryBuilder.cs",
                    "PreLiveComparison.cs",
                    "PreLiveComparisonQueryBuilder.cs",
                    "PriceRating.cs",
                    "PriceRatingColorOffset.cs",
                    "PriceRatingColorOffsetQueryBuilder.cs",
                    "PriceRatingEntry.cs",
                    "PriceRatingEntryQueryBuilder.cs",
                    "PriceRatingQueryBuilder.cs",
                    "PriceRatingRoot.cs",
                    "PriceRatingRootQueryBuilder.cs",
                    "ProcessStep.cs",
                    "ProcessStepQueryBuilder.cs",
                    "Producer.cs",
                    "ProducerBullet.cs",
                    "ProducerBulletQueryBuilder.cs",
                    "ProducerQueryBuilder.cs",
                    "Production.cs",
                    "ProductionMonth.cs",
                    "ProductionMonthQueryBuilder.cs",
                    "ProductionQueryBuilder.cs",
                    "ProductionValue.cs",
                    "ProductionValueQueryBuilder.cs",
                    "PushNotification.cs",
                    "PushNotificationQueryBuilder.cs",
                    "Query.cs",
                    "QueryQueryBuilder.cs",
                    "Report.cs",
                    "ReportCell.cs",
                    "ReportCellQueryBuilder.cs",
                    "ReportQueryBuilder.cs",
                    "ReportRoot.cs",
                    "ReportRootQueryBuilder.cs",
                    "Resolution.cs",
                    "Sensor.cs",
                    "SensorHistory.cs",
                    "SensorHistoryQueryBuilder.cs",
                    "SensorHistoryValue.cs",
                    "SensorHistoryValueQueryBuilder.cs",
                    "SensorQueryBuilder.cs",
                    "SignupStatus.cs",
                    "SignupStatusQueryBuilder.cs",
                    "SkipDirective.cs",
                    "Subscription.cs",
                    "SubscriptionQueryBuilder.cs",
                    "Thermostat.cs",
                    "ThermostatCapability.cs",
                    "ThermostatCapabilityQueryBuilder.cs",
                    "ThermostatMeasurement.cs",
                    "ThermostatMeasurementQueryBuilder.cs",
                    "ThermostatMeasurements.cs",
                    "ThermostatMeasurementsQueryBuilder.cs",
                    "ThermostatMode.cs",
                    "ThermostatModeQueryBuilder.cs",
                    "ThermostatMutation.cs",
                    "ThermostatMutationQueryBuilder.cs",
                    "ThermostatQueryBuilder.cs",
                    "ThermostatState.cs",
                    "ThermostatStateQueryBuilder.cs",
                    "Wallet.cs",
                    "WalletQueryBuilder.cs",
                    "Weather.cs",
                    "WeatherEntry.cs",
                    "WeatherEntryQueryBuilder.cs",
                    "WeatherQueryBuilder.cs"
                });

                var fileSizes = files.Where(f => f.Name != "BaseClasses.cs").Select(f => f.Length);
                fileSizes.ShouldBe(
                    new long[]
                {
                    370, 399, 1295, 1082, 902, 4131, 443, 493, 2056, 1831, 379, 1038, 1076, 1609, 1675, 680, 418, 1507, 422, 1334, 716, 415, 1365, 4006, 887, 686, 3557, 4906, 402, 1312, 490, 2119, 537, 2296, 1149, 6812, 371, 1153, 495, 600, 2706, 2476, 413, 1389, 385, 1215, 368, 5985, 518, 2132, 1881, 845, 7805, 803, 1454, 417, 1433, 4626, 17076, 731, 1550, 551, 2587, 9743, 896, 5100, 1025, 476, 3221, 7042, 358, 1339, 467, 425, 1445, 1890, 499, 2175, 455, 1733, 545, 2501, 691, 495, 1921, 505, 2085, 3516, 679, 3759, 512, 2080, 600, 461, 1749, 2837, 996, 719, 3864, 5591, 822, 4380, 444, 1682, 347, 1283, 588, 675, 3451, 2781, 374, 1105, 404, 513, 483, 1902, 472, 1765, 2209, 483, 2143, 706, 777, 4324, 862, 454, 1756, 796, 4433, 508, 2005, 425, 1388, 413, 2590, 4949, 510, 2124, 482, 1874, 485, 1154, 3506, 1874
                });

                var expectedOutput = GetTestResource("ExpectedMultipleFilesContext.Avatar");
                File.ReadAllText(Path.Combine(directoryInfo.FullName, "Avatar.cs")).ShouldBe(expectedOutput);
                expectedOutput = GetTestResource("ExpectedMultipleFilesContext.Home");
                File.ReadAllText(Path.Combine(directoryInfo.FullName, "Home.cs")).ShouldBe(expectedOutput);
                expectedOutput = GetTestResource("ExpectedMultipleFilesContext.IncludeDirective");
                File.ReadAllText(Path.Combine(directoryInfo.FullName, "IncludeDirective.cs")).ShouldBe(expectedOutput);
                expectedOutput = GetTestResource("ExpectedMultipleFilesContext.MutationQueryBuilder");
                File.ReadAllText(Path.Combine(directoryInfo.FullName, "MutationQueryBuilder.cs")).ShouldBe(expectedOutput);
            }
            finally
            {
                Directory.Delete(directoryInfo.FullName, true);
            }
        }
    public void MultipleFileGeneration()
    {
        var configuration =
            new GraphQlGeneratorConfiguration
        {
            CommentGeneration = CommentGenerationOption.CodeSummary | CommentGenerationOption.DescriptionAttribute,
            CSharpVersion     = CSharpVersion.Newest
        };

        var generator = new GraphQlGenerator(configuration);

        var tempPath      = Path.GetTempPath();
        var directoryInfo = Directory.CreateDirectory(Path.Combine(tempPath, "GraphQlGeneratorTest"));

        try
        {
            var context = new MultipleFileGenerationContext(DeserializeTestSchema("TestSchema2"), directoryInfo.FullName, "GraphQlGeneratorTest", "GraphQlGeneratorTest.csproj");
            generator.Generate(context);

            var files     = directoryInfo.GetFiles().OrderBy(f => f.Name).ToArray();
            var fileNames = files.Select(f => f.Name);
            fileNames.ShouldBe(
                new[]
            {
                "About.cs",
                "AboutItem.cs",
                "AboutItemQueryBuilder.cs",
                "AboutQueryBuilder.cs",
                "Address.cs",
                "AddressQueryBuilder.cs",
                "AppState.cs",
                "AppStateFronScreen.cs",
                "AppStateFronScreenMutation.cs",
                "AppStateFronScreenQueryBuilder.cs",
                "AppStateJourney.cs",
                "AppStateJourneyMutation.cs",
                "AppStateJourneyQueryBuilder.cs",
                "AppStateMutation.cs",
                "AppStateQueryBuilder.cs",
                "Avatar.cs",
                "AwayMode.cs",
                "AwayModeQueryBuilder.cs",
                "AwayModeSettings.cs",
                "AwayModeSettingsQueryBuilder.cs",
                "BaseClasses.cs",
                "Comparison.cs",
                "ComparisonData.cs",
                "ComparisonDataQueryBuilder.cs",
                "ComparisonQueryBuilder.cs",
                "Consumption.cs",
                "ConsumptionMonth.cs",
                "ConsumptionMonthQueryBuilder.cs",
                "ConsumptionQueryBuilder.cs",
                "CreditCard.cs",
                "CreditCardQueryBuilder.cs",
                "DayNightSchedule.cs",
                "DayNightScheduleQueryBuilder.cs",
                "DayNightScheduleSettings.cs",
                "DayNightScheduleSettingsQueryBuilder.cs",
                "Disaggregation.cs",
                "DisaggregationQueryBuilder.cs",
                "EnergyDeal.cs",
                "EnergyDealQueryBuilder.cs",
                "Feed.cs",
                "FeedItem.cs",
                "FeedItemQueryBuilder.cs",
                "FeedQueryBuilder.cs",
                "GqlMutationError.cs",
                "GqlMutationErrorQueryBuilder.cs",
                "GqlMutationGeneralResponse.cs",
                "GqlMutationGeneralResponseQueryBuilder.cs",
                "GraphQlGeneratorTest.csproj",
                "GraphQlTypes.cs",
                "Greeting.cs",
                "GreetingQueryBuilder.cs",
                "Home.cs",
                "HomeMutation.cs",
                "HomeMutationQueryBuilder.cs",
                "HomeProfileQuestion.cs",
                "HomeProfileQuestionAnswer.cs",
                "HomeProfileQuestionInput.cs",
                "HomeProfileQuestionInputQueryBuilder.cs",
                "HomeProfileQuestionQueryBuilder.cs",
                "HomeQueryBuilder.cs",
                "IncludeDirective.cs",
                "Invoice.cs",
                "InvoicePayment.cs",
                "InvoicePaymentQueryBuilder.cs",
                "InvoiceQueryBuilder.cs",
                "InvoiceSection.cs",
                "InvoiceSectionQueryBuilder.cs",
                "Me.cs",
                "MeMutation.cs",
                "MeMutationQueryBuilder.cs",
                "MeQueryBuilder.cs",
                "Mutation.cs",
                "MutationQueryBuilder.cs",
                "PairableDevice.cs",
                "PairableDeviceOAuth.cs",
                "PairableDeviceOAuthQueryBuilder.cs",
                "PairableDeviceQueryBuilder.cs",
                "PairDeviceResult.cs",
                "PairDeviceResultQueryBuilder.cs",
                "PaymentMethod.cs",
                "PaymentMethodQueryBuilder.cs",
                "PreLiveComparison.cs",
                "PreLiveComparisonQueryBuilder.cs",
                "PriceRating.cs",
                "PriceRatingColorOffset.cs",
                "PriceRatingColorOffsetQueryBuilder.cs",
                "PriceRatingEntry.cs",
                "PriceRatingEntryQueryBuilder.cs",
                "PriceRatingQueryBuilder.cs",
                "PriceRatingRoot.cs",
                "PriceRatingRootQueryBuilder.cs",
                "ProcessStep.cs",
                "ProcessStepQueryBuilder.cs",
                "Producer.cs",
                "ProducerBullet.cs",
                "ProducerBulletQueryBuilder.cs",
                "ProducerQueryBuilder.cs",
                "Production.cs",
                "ProductionMonth.cs",
                "ProductionMonthQueryBuilder.cs",
                "ProductionQueryBuilder.cs",
                "ProductionValue.cs",
                "ProductionValueQueryBuilder.cs",
                "PushNotification.cs",
                "PushNotificationQueryBuilder.cs",
                "Query.cs",
                "QueryQueryBuilder.cs",
                "Report.cs",
                "ReportCell.cs",
                "ReportCellQueryBuilder.cs",
                "ReportQueryBuilder.cs",
                "ReportRoot.cs",
                "ReportRootQueryBuilder.cs",
                "Resolution.cs",
                "Sensor.cs",
                "SensorHistory.cs",
                "SensorHistoryQueryBuilder.cs",
                "SensorHistoryValue.cs",
                "SensorHistoryValueQueryBuilder.cs",
                "SensorQueryBuilder.cs",
                "SignupStatus.cs",
                "SignupStatusQueryBuilder.cs",
                "SkipDirective.cs",
                "Subscription.cs",
                "SubscriptionQueryBuilder.cs",
                "Thermostat.cs",
                "ThermostatCapability.cs",
                "ThermostatCapabilityQueryBuilder.cs",
                "ThermostatMeasurement.cs",
                "ThermostatMeasurementQueryBuilder.cs",
                "ThermostatMeasurements.cs",
                "ThermostatMeasurementsQueryBuilder.cs",
                "ThermostatMode.cs",
                "ThermostatModeQueryBuilder.cs",
                "ThermostatMutation.cs",
                "ThermostatMutationQueryBuilder.cs",
                "ThermostatQueryBuilder.cs",
                "ThermostatState.cs",
                "ThermostatStateQueryBuilder.cs",
                "Wallet.cs",
                "WalletQueryBuilder.cs",
                "Weather.cs",
                "WeatherEntry.cs",
                "WeatherEntryQueryBuilder.cs",
                "WeatherQueryBuilder.cs"
            });

            var fileSizes = files.Where(f => f.Name != "BaseClasses.cs").Select(f => f.Length);
            fileSizes.ShouldBe(
                new long[]
            {
                446, 475, 1371, 1158, 978, 4207, 519, 569, 2132, 1907, 455, 1114, 1152, 1685, 1751, 756, 494, 1583, 498, 1410, 792, 491, 1441, 4082, 963, 762, 3633, 4982, 478, 1388, 566, 2195, 613, 2372, 1225, 6888, 447, 1229, 571, 676, 2782, 2552, 489, 1465, 461, 1291, 368, 6061, 594, 2208, 1957, 921, 7881, 879, 1530, 493, 1509, 4702, 17152, 807, 1626, 627, 2663, 9819, 972, 5176, 1101, 552, 3297, 7118, 434, 1415, 543, 501, 1521, 1966, 575, 2251, 531, 1809, 621, 2577, 767, 571, 1997, 581, 2161, 3592, 755, 3835, 588, 2156, 676, 537, 1825, 2913, 1072, 795, 3940, 5667, 898, 4456, 520, 1758, 423, 1359, 664, 751, 3527, 2857, 450, 1181, 480, 589, 559, 1978, 548, 1841, 2285, 559, 2219, 782, 853, 4400, 938, 530, 1832, 872, 4509, 584, 2081, 501, 1464, 489, 2666, 5025, 586, 2200, 558, 1950, 561, 1230, 3582, 1950
            });

            var expectedOutput = GetTestResource("ExpectedMultipleFilesContext.Avatar");
            File.ReadAllText(Path.Combine(directoryInfo.FullName, "Avatar.cs")).ShouldBe(expectedOutput);
            expectedOutput = GetTestResource("ExpectedMultipleFilesContext.Home");
            File.ReadAllText(Path.Combine(directoryInfo.FullName, "Home.cs")).ShouldBe(expectedOutput);
            expectedOutput = GetTestResource("ExpectedMultipleFilesContext.IncludeDirective");
            File.ReadAllText(Path.Combine(directoryInfo.FullName, "IncludeDirective.cs")).ShouldBe(expectedOutput);
            expectedOutput = GetTestResource("ExpectedMultipleFilesContext.MutationQueryBuilder");
            File.ReadAllText(Path.Combine(directoryInfo.FullName, "MutationQueryBuilder.cs")).ShouldBe(expectedOutput);
        }
        finally
        {
            Directory.Delete(directoryInfo.FullName, true);
        }
    }
예제 #26
0
        public void GenerateDataClassesWithTypeConfiguration()
        {
            GraphQlGeneratorConfiguration.IntegerTypeMapping           = IntegerTypeMapping.Int64;
            GraphQlGeneratorConfiguration.FloatTypeMapping             = FloatTypeMapping.Double;
            GraphQlGeneratorConfiguration.BooleanTypeMapping           = BooleanTypeMapping.Custom;
            GraphQlGeneratorConfiguration.IdTypeMapping                = IdTypeMapping.String;
            GraphQlGeneratorConfiguration.GeneratePartialClasses       = false;
            GraphQlGeneratorConfiguration.PropertyGeneration           = PropertyGenerationOption.BackingField;
            GraphQlGeneratorConfiguration.CustomScalarFieldTypeMapping =
                (baseType, valueType, valueName) => valueType.Name == "Boolean" ? "bool" : GraphQlGeneratorConfiguration.DefaultScalarFieldTypeMapping(baseType, valueType, valueName);

            var stringBuilder = new StringBuilder();

            GraphQlGenerator.GenerateDataClasses(TestSchema, stringBuilder);

            var expectedDataClasses = GetTestResource("ExpectedDataClassesWithTypeConfiguration");

            stringBuilder.ToString().ShouldBe(expectedDataClasses);
        }
예제 #27
0
    public void Execute(GeneratorExecutionContext context)
    {
        if (context.Compilation is not CSharpCompilation compilation)
        {
            context.ReportDiagnostic(
                Diagnostic.Create(
                    DescriptorParameterError,
                    Location.None,
                    "incompatible language: " + context.Compilation.Language));

            return;
        }

        try
        {
            context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + "ServiceUrl", out var serviceUrl);
            var isServiceUrlMissing = String.IsNullOrWhiteSpace(serviceUrl);
            var graphQlSchemaFiles  = context.AdditionalFiles.Where(f => Path.GetFileName(f.Path).EndsWith(".gql.schema.json", StringComparison.OrdinalIgnoreCase)).ToList();
            var indexRegexScalarFieldTypeMappingProviderConfigurationFile =
                graphQlSchemaFiles.FindIndex(f => String.Equals(Path.GetFileName(f.Path), FileNameRegexScalarFieldTypeMappingProviderConfiguration, StringComparison.OrdinalIgnoreCase));

            ICollection <RegexScalarFieldTypeMappingRule> regexScalarFieldTypeMappingProviderRules = null;
            if (indexRegexScalarFieldTypeMappingProviderConfigurationFile != -1)
            {
                regexScalarFieldTypeMappingProviderRules =
                    JsonConvert.DeserializeObject <ICollection <RegexScalarFieldTypeMappingRule> >(
                        graphQlSchemaFiles[indexRegexScalarFieldTypeMappingProviderConfigurationFile].GetText().ToString());

                graphQlSchemaFiles.RemoveAt(indexRegexScalarFieldTypeMappingProviderConfigurationFile);
            }

            var isSchemaFileSpecified = graphQlSchemaFiles.Any();
            if (isServiceUrlMissing && !isSchemaFileSpecified)
            {
                context.ReportDiagnostic(
                    Diagnostic.Create(
                        DescriptorInfo,
                        Location.None,
                        "Neither \"GraphQlClientGenerator_ServiceUrl\" parameter nor GraphQL JSON schema additional file specified; terminating. "));

                return;
            }

            if (!isServiceUrlMissing && isSchemaFileSpecified)
            {
                context.ReportDiagnostic(
                    Diagnostic.Create(
                        DescriptorParameterError,
                        Location.None,
                        "\"GraphQlClientGenerator_ServiceUrl\" parameter and GraphQL JSON schema additional file are mutually exclusive. "));

                return;
            }

            context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + "Namespace", out var @namespace);
            if (String.IsNullOrWhiteSpace(@namespace))
            {
                var root = (CompilationUnitSyntax)compilation.SyntaxTrees.FirstOrDefault()?.GetRoot();
                var namespaceIdentifier = (IdentifierNameSyntax)root?.Members.OfType <NamespaceDeclarationSyntax>().FirstOrDefault()?.Name;
                if (namespaceIdentifier == null)
                {
                    context.ReportDiagnostic(
                        Diagnostic.Create(
                            DescriptorParameterError,
                            Location.None,
                            "\"GraphQlClientGenerator_Namespace\" required"));

                    return;
                }

                @namespace = namespaceIdentifier.Identifier.ValueText;

                context.ReportDiagnostic(
                    Diagnostic.Create(
                        DescriptorInfo,
                        Location.None,
                        $"\"GraphQlClientGenerator_Namespace\" not specified; using \"{@namespace}\""));
            }

            var configuration = new GraphQlGeneratorConfiguration {
                TreatUnknownObjectAsScalar = true
            };

            context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + "ClassPrefix", out var classPrefix);
            configuration.ClassPrefix = classPrefix;

            context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + "ClassSuffix", out var classSuffix);
            configuration.ClassSuffix = classSuffix;

            if (compilation.LanguageVersion >= LanguageVersion.CSharp6)
            {
                configuration.CSharpVersion =
                    compilation.Options.NullableContextOptions == NullableContextOptions.Disable
                        ? CSharpVersion.Newest
                        : CSharpVersion.NewestWithNullableReferences;
            }

            var currentParameterName = "IncludeDeprecatedFields";
            context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + currentParameterName, out var includeDeprecatedFieldsRaw);
            configuration.IncludeDeprecatedFields = !String.IsNullOrWhiteSpace(includeDeprecatedFieldsRaw) && Convert.ToBoolean(includeDeprecatedFieldsRaw);

            currentParameterName = "HttpMethod";
            if (!context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + currentParameterName, out var httpMethod))
            {
                httpMethod = "POST";
            }

            currentParameterName = "CommentGeneration";
            context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + currentParameterName, out var commentGenerationRaw);
            configuration.CommentGeneration =
                String.IsNullOrWhiteSpace(commentGenerationRaw)
                    ? CommentGenerationOption.CodeSummary
                    : (CommentGenerationOption)Enum.Parse(typeof(CommentGenerationOption), commentGenerationRaw, true);

            currentParameterName = "FloatTypeMapping";
            context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + currentParameterName, out var floatTypeMappingRaw);
            configuration.FloatTypeMapping =
                String.IsNullOrWhiteSpace(floatTypeMappingRaw)
                    ? FloatTypeMapping.Decimal
                    : (FloatTypeMapping)Enum.Parse(typeof(FloatTypeMapping), floatTypeMappingRaw, true);

            currentParameterName = "BooleanTypeMapping";
            context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + currentParameterName, out var booleanTypeMappingRaw);
            configuration.BooleanTypeMapping =
                String.IsNullOrWhiteSpace(booleanTypeMappingRaw)
                    ? BooleanTypeMapping.Boolean
                    : (BooleanTypeMapping)Enum.Parse(typeof(BooleanTypeMapping), booleanTypeMappingRaw, true);

            currentParameterName = "IdTypeMapping";
            context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + currentParameterName, out var idTypeMappingRaw);
            configuration.IdTypeMapping =
                String.IsNullOrWhiteSpace(idTypeMappingRaw)
                    ? IdTypeMapping.Guid
                    : (IdTypeMapping)Enum.Parse(typeof(IdTypeMapping), idTypeMappingRaw, true);

            currentParameterName = "JsonPropertyGeneration";
            context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + currentParameterName, out var jsonPropertyGenerationRaw);
            configuration.JsonPropertyGeneration =
                String.IsNullOrWhiteSpace(jsonPropertyGenerationRaw)
                    ? JsonPropertyGenerationOption.CaseInsensitive
                    : (JsonPropertyGenerationOption)Enum.Parse(typeof(JsonPropertyGenerationOption), jsonPropertyGenerationRaw, true);

            currentParameterName = "EnumValueNaming";
            context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + currentParameterName, out var enumValueNamingRaw);
            configuration.EnumValueNaming =
                String.IsNullOrWhiteSpace(enumValueNamingRaw)
                    ? EnumValueNamingOption.CSharp
                    : (EnumValueNamingOption)Enum.Parse(typeof(EnumValueNamingOption), enumValueNamingRaw, true);

            currentParameterName = "CustomClassMapping";
            context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + currentParameterName, out var customClassMappingRaw);
            if (!KeyValueParameterParser.TryGetCustomClassMapping(
                    customClassMappingRaw?.Split(new[] { '|', ';', ' ' }, StringSplitOptions.RemoveEmptyEntries),
                    out var customMapping,
                    out var customMappingParsingErrorMessage))
            {
                context.ReportDiagnostic(Diagnostic.Create(DescriptorParameterError, Location.None, customMappingParsingErrorMessage));
                return;
            }

            foreach (var kvp in customMapping)
            {
                configuration.CustomClassNameMapping.Add(kvp);
            }

            currentParameterName = "Headers";
            context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + currentParameterName, out var headersRaw);
            if (!KeyValueParameterParser.TryGetCustomHeaders(
                    headersRaw?.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries),
                    out var headers,
                    out var headerParsingErrorMessage))
            {
                context.ReportDiagnostic(Diagnostic.Create(DescriptorParameterError, Location.None, headerParsingErrorMessage));
                return;
            }

            currentParameterName = "ScalarFieldTypeMappingProvider";
            if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue(BuildPropertyKeyPrefix + currentParameterName, out var scalarFieldTypeMappingProviderName))
            {
                if (regexScalarFieldTypeMappingProviderRules != null)
                {
                    context.ReportDiagnostic(Diagnostic.Create(DescriptorParameterError, Location.None, "\"GraphQlClientGenerator_ScalarFieldTypeMappingProvider\" and RegexScalarFieldTypeMappingProviderConfiguration are mutually exclusive"));
                    return;
                }

                if (String.IsNullOrWhiteSpace(scalarFieldTypeMappingProviderName))
                {
                    context.ReportDiagnostic(Diagnostic.Create(DescriptorParameterError, Location.None, "\"GraphQlClientGenerator_ScalarFieldTypeMappingProvider\" value missing"));
                    return;
                }

                var scalarFieldTypeMappingProviderType = Type.GetType(scalarFieldTypeMappingProviderName);
                if (scalarFieldTypeMappingProviderType == null)
                {
                    context.ReportDiagnostic(Diagnostic.Create(DescriptorParameterError, Location.None, $"ScalarFieldTypeMappingProvider \"{scalarFieldTypeMappingProviderName}\" not found"));
                    return;
                }

                var scalarFieldTypeMappingProvider = (IScalarFieldTypeMappingProvider)Activator.CreateInstance(scalarFieldTypeMappingProviderType);
                configuration.ScalarFieldTypeMappingProvider = scalarFieldTypeMappingProvider;
            }
            else if (regexScalarFieldTypeMappingProviderRules?.Count > 0)
            {
                configuration.ScalarFieldTypeMappingProvider = new RegexScalarFieldTypeMappingProvider(regexScalarFieldTypeMappingProviderRules);
            }

            var graphQlSchemas = new List <(string TargetFileName, GraphQlSchema Schema)>();
            if (isSchemaFileSpecified)
            {
                foreach (var schemaFile in graphQlSchemaFiles)
                {
                    var targetFileName = Path.GetFileNameWithoutExtension(schemaFile.Path) + ".cs";
                    graphQlSchemas.Add((targetFileName, GraphQlGenerator.DeserializeGraphQlSchema(schemaFile.GetText().ToString())));
                }
            }
            else
            {
                graphQlSchemas.Add((FileNameGraphQlClientSource, GraphQlGenerator.RetrieveSchema(new HttpMethod(httpMethod), serviceUrl, headers).GetAwaiter().GetResult()));
                context.ReportDiagnostic(
                    Diagnostic.Create(
                        DescriptorInfo,
                        Location.None,
                        "GraphQl schema fetched successfully from " + serviceUrl));
            }

            var generator = new GraphQlGenerator(configuration);

            foreach (var(targetFileName, schema) in graphQlSchemas)
            {
                var builder = new StringBuilder();
                using (var writer = new StringWriter(builder))
                    generator.WriteFullClientCSharpFile(schema, @namespace, writer);

                context.AddSource(targetFileName, SourceText.From(builder.ToString(), Encoding.UTF8));
            }

            context.ReportDiagnostic(
                Diagnostic.Create(
                    DescriptorInfo,
                    Location.None,
                    "GraphQlClientGenerator task completed successfully. "));
        }
        catch (Exception exception)
        {
            context.ReportDiagnostic(Diagnostic.Create(DescriptorGenerationError, Location.None, exception.Message));
        }
    }
예제 #28
0
        public static async Task <IReadOnlyCollection <FileInfo> > GenerateClientSourceCode(ProgramOptions options)
        {
            var isServiceUrlMissing = String.IsNullOrWhiteSpace(options.ServiceUrl);

            if (isServiceUrlMissing && String.IsNullOrWhiteSpace(options.SchemaFileName))
            {
                System.Console.WriteLine("ERROR: Either \"serviceUrl\" or \"schemaFileName\" parameter must be specified. ");
                Environment.Exit(4);
            }

            if (!isServiceUrlMissing && !String.IsNullOrWhiteSpace(options.SchemaFileName))
            {
                System.Console.WriteLine("ERROR: \"serviceUrl\" and \"schemaFileName\" parameters are mutually exclusive. ");
                Environment.Exit(5);
            }

            GraphQlSchema schema;

            if (isServiceUrlMissing)
            {
                schema = GraphQlGenerator.DeserializeGraphQlSchema(await File.ReadAllTextAsync(options.SchemaFileName));
            }
            else
            {
                if (!KeyValueParameterParser.TryGetCustomHeaders(options.Headers, out var headers, out var headerParsingErrorMessage))
                {
                    System.Console.WriteLine("ERROR: " + headerParsingErrorMessage);
                    Environment.Exit(3);
                }

                schema = await GraphQlGenerator.RetrieveSchema(options.ServiceUrl, headers);
            }

            var generatorConfiguration =
                new GraphQlGeneratorConfiguration
            {
                CSharpVersion          = options.CSharpVersion,
                ClassPrefix            = options.ClassPrefix,
                ClassSuffix            = options.ClassSuffix,
                GeneratePartialClasses = options.PartialClasses,
                MemberAccessibility    = options.MemberAccessibility,
                IdTypeMapping          = options.IdTypeMapping,
                FloatTypeMapping       = options.FloatTypeMapping,
                JsonPropertyGeneration = options.JsonPropertyAttribute
            };

            if (!KeyValueParameterParser.TryGetCustomClassMapping(options.ClassMapping, out var customMapping, out var customMappingParsingErrorMessage))
            {
                System.Console.WriteLine("ERROR: " + customMappingParsingErrorMessage);
                Environment.Exit(3);
            }

            foreach (var kvp in customMapping)
            {
                generatorConfiguration.CustomClassNameMapping.Add(kvp);
            }

            var generator = new GraphQlGenerator(generatorConfiguration);

            if (options.OutputType == OutputType.SingleFile)
            {
                await File.WriteAllTextAsync(options.OutputPath, generator.GenerateFullClientCSharpFile(schema, options.Namespace));

                return(new[] { new FileInfo(options.OutputPath) });
            }

            var multipleFileGenerationContext = new MultipleFileGenerationContext(schema, options.OutputPath, options.Namespace);

            generator.Generate(multipleFileGenerationContext);
            return(multipleFileGenerationContext.Files);
        }
 public GraphQlGeneratorTest(ITestOutputHelper outputHelper)
 {
     _outputHelper = outputHelper;
     GraphQlGeneratorConfiguration.Reset();
 }
 public virtual void BeforeGeneration(GraphQlGeneratorConfiguration configuration) => Configuration = configuration;