private void ThrowsServiceDefinitionException(string definition, string message)
        {
            var parser    = new FsdParser();
            var service   = parser.ParseDefinition(new ServiceDefinitionText("TestApi.fsd", definition));
            var generator = new CSharpGenerator {
                GeneratorName = "CodeGenTests"
            };
            Action action = () => generator.GenerateOutput(service);

            action.Should().Throw <ServiceDefinitionException>().WithMessage(message);
        }
示例#2
0
        public void GenerateExampleApiTypeScript_IncludesEnums()
        {
            ServiceInfo  service;
            const string fileName = "Facility.CodeGen.JavaScript.UnitTests.ExampleApi.fsd";
            var          parser   = new FsdParser();
            var          stream   = GetType().GetTypeInfo().Assembly.GetManifestResourceStream(fileName) !;

            Assert.IsNotNull(stream);
            using (var reader = new StreamReader(stream))
                service = parser.ParseDefinition(new ServiceDefinitionText(Path.GetFileName(fileName), reader.ReadToEnd()));

            var generator = new JavaScriptGenerator
            {
                GeneratorName = "JavaScriptGeneratorTests",
                TypeScript    = true,
                NewLine       = "\n",
            };
            var result = generator.GenerateOutput(service);

            Assert.IsNotNull(result);

            var          typesFile     = result.Files.Single(f => f.Name == "exampleApiTypes.ts");
            const string expectedEnums = @"
/** Identifies a widget field. */
export enum WidgetField {
	/** The 'id' field. */
	id = 'id',

	/** The 'name' field. */
	name = 'name',

	/**
	 * The 'weight' field.
	 * @deprecated
	 */
	weight = 'weight',
}

/**
 * An obsolete enum.
 * @deprecated
 */
export enum ObsoleteEnum {
	unused = 'unused',
}";

            Assert.That(typesFile.Text, Contains.Substring(expectedEnums));

            const string expectedEnumUsage = @"widgetField?: WidgetField;";

            Assert.That(typesFile.Text, Contains.Substring(expectedEnumUsage));
        }
        public void GenerateEdgeCases()
        {
            string fileName = Path.Combine(TestUtility.GetSolutionDirectory(), "tools", "EdgeCases.fsd");
            var    parser   = new FsdParser();
            var    service  = parser.ParseDefinition(
                new ServiceDefinitionText(Path.GetFileName(fileName), File.ReadAllText(fileName)));

            var generator = new CSharpGenerator {
                GeneratorName = nameof(CSharpGeneratorTests)
            };

            generator.GenerateOutput(service);
        }
示例#4
0
        public void GenerateConformanceApi()
        {
            string fileName = Path.Combine(TestUtility.GetSolutionDirectory(), "conformance", "ConformanceApi.fsd");
            var    parser   = new FsdParser();
            var    service  = parser.ParseDefinition(
                new ServiceDefinitionText(Path.GetFileName(fileName), File.ReadAllText(fileName)));

            var generator = new CSharpGenerator {
                GeneratorName = "CodeGenTests"
            };
            var output = generator.GenerateOutput(service);

            output.Files.Count(x => x.Name == "IConformanceApi.g.cs").Should().Be(1);
        }
示例#5
0
        public void GenerateEdgeCases()
        {
            string fsdText;

            using (var fsdTextReader = new StreamReader(GetType().Assembly.GetManifestResourceStream("Facility.CodeGen.CSharp.UnitTests.EdgeCases.fsd") !))
                fsdText = fsdTextReader.ReadToEnd();

            var parser  = new FsdParser();
            var service = parser.ParseDefinition(new ServiceDefinitionText("EdgeCases.fsd", fsdText));

            var generator = new CSharpGenerator {
                GeneratorName = nameof(CSharpGeneratorTests)
            };

            generator.GenerateOutput(service);
        }
示例#6
0
        public void OverrideNamespace()
        {
            var definition = "[csharp(namespace: DefinitionNamespace)] service TestApi { method do {}: {} }";
            var parser     = new FsdParser();
            var service    = parser.ParseDefinition(new ServiceDefinitionText("TestApi.fsd", definition));
            var generator  = new CSharpGenerator {
                GeneratorName = nameof(CSharpGeneratorTests), NamespaceName = "OverrideNamespace"
            };
            var output = generator.GenerateOutput(service);

            foreach (var file in output.Files)
            {
                StringAssert.Contains("namespace OverrideNamespace", file.Text);
                StringAssert.DoesNotContain("DefinitionNamespace", file.Text);
            }
        }
示例#7
0
        public void GenerateExampleApiSuccess()
        {
            ServiceInfo  service;
            const string fileName = "Facility.CodeGen.CSharp.UnitTests.ExampleApi.fsd";
            var          parser   = new FsdParser();

            using (var reader = new StreamReader(GetType().GetTypeInfo().Assembly.GetManifestResourceStream(fileName)))
                service = parser.ParseDefinition(new NamedText(Path.GetFileName(fileName), reader.ReadToEnd()));

            var generator = new CSharpGenerator
            {
                GeneratorName = "CSharpGeneratorTests",
            };

            generator.GenerateOutput(service);
        }
    public void GenerateConformanceApi()
    {
        string fsdText;

        using (var fsdTextReader = new StreamReader(GetType().Assembly.GetManifestResourceStream("Facility.ConformanceApi.UnitTests.ConformanceApi.fsd") !))
            fsdText = fsdTextReader.ReadToEnd();

        var parser  = new FsdParser();
        var service = parser.ParseDefinition(
            new ServiceDefinitionText("ConformanceApi.fsd", fsdText));

        var generator = new CSharpGenerator {
            GeneratorName = "CodeGenTests"
        };
        var output = generator.GenerateOutput(service);

        output.Files.Count(x => x.Name == "IConformanceApi.g.cs").Should().Be(1);
    }
示例#9
0
        public void GenerateConformanceApiSuccess()
        {
            ServiceInfo  service;
            const string fileName = "Facility.CodeGen.AspNet.UnitTests.ConformanceApi.fsd";
            var          parser   = new FsdParser();
            var          stream   = GetType().GetTypeInfo().Assembly.GetManifestResourceStream(fileName);

            Assert.IsNotNull(stream);
            using (var reader = new StreamReader(stream))
                service = parser.ParseDefinition(new ServiceDefinitionText(Path.GetFileName(fileName), reader.ReadToEnd()));

            var generator = new AspNetGenerator
            {
                GeneratorName = "AspNetGeneratorTests",
            };

            generator.GenerateOutput(service);
        }
        public void GenerateEnumStringConstants()
        {
            const string definition = "[csharp] service TestApi { enum Answer { yes, no, maybe } }";
            var          parser     = new FsdParser();
            var          service    = parser.ParseDefinition(new ServiceDefinitionText("TestApi.fsd", definition));
            var          generator  = new CSharpGenerator {
                GeneratorName = nameof(CSharpGeneratorTests)
            };

            var output = generator.GenerateOutput(service);

            var file = output.Files.First(x => x.Name == "Answer.g.cs");

            StringAssert.Contains("public static class Strings", file.Text);
            StringAssert.Contains("public const string Yes = \"yes\";", file.Text);
            StringAssert.Contains("public const string No = \"no\";", file.Text);
            StringAssert.Contains("public const string Maybe = \"maybe\";", file.Text);
        }
示例#11
0
        public void GenerateExampleApiSuccess(bool typeScript)
        {
            ServiceInfo  service;
            const string fileName = "Facility.CodeGen.JavaScript.UnitTests.ExampleApi.fsd";
            var          parser   = new FsdParser();
            var          stream   = GetType().GetTypeInfo().Assembly.GetManifestResourceStream(fileName);

            Assert.IsNotNull(stream);
            using (var reader = new StreamReader(stream))
                service = parser.ParseDefinition(new NamedText(Path.GetFileName(fileName), reader.ReadToEnd()));

            var generator = new JavaScriptGenerator
            {
                GeneratorName = "JavaScriptGeneratorTests",
                TypeScript    = typeScript,
            };

            generator.GenerateOutput(service);
        }
        public FacilityServiceDefinitionDocumentHandler(ILanguageServer router)
        {
            m_router = router;

            m_parser = new FsdParser();
        }
示例#13
0
        /// <summary>
        /// Called to execute the code generator application.
        /// </summary>
        /// <param name="args">The command-line arguments.</param>
        /// <returns>The exit code.</returns>
        public int Run(IReadOnlyList <string> args)
        {
            try
            {
                var argsReader = new ArgsReader(args);
                if (argsReader.ReadHelpFlag())
                {
                    foreach (string line in Description)
                    {
                        System.Console.WriteLine(line);
                    }
                    System.Console.WriteLine();
                    WriteUsage();
                    return(0);
                }

                var generator = CreateGenerator(argsReader);
                generator.GeneratorName = s_assemblyName;
                if (SupportsCustomIndent)
                {
                    string indentText = argsReader.ReadIndentOption();
                    if (indentText != null)
                    {
                        generator.IndentText = indentText;
                    }
                }
                if (SupportsCustomNewLine)
                {
                    string newLine = argsReader.ReadNewLineOption();
                    if (newLine != null)
                    {
                        generator.NewLine = newLine;
                    }
                }

                string serviceName = argsReader.ReadServiceNameOption();
                bool   shouldClean = SupportsClean && argsReader.ReadCleanFlag();
                bool   isQuiet     = argsReader.ReadQuietFlag();
                bool   isVerify    = argsReader.ReadVerifyFlag();
                bool   isDryRun    = argsReader.ReadDryRunFlag();

                string inputPath = argsReader.ReadArgument();
                if (inputPath == null)
                {
                    throw new ArgsReaderException("Missing input path.");
                }

                string outputPath = argsReader.ReadArgument();
                if (outputPath == null)
                {
                    throw new ArgsReaderException("Missing output path.");
                }

                argsReader.VerifyComplete();

                NamedText input;
                if (inputPath == "-")
                {
                    input = new NamedText("", System.Console.In.ReadToEnd());
                }
                else
                {
                    if (!File.Exists(inputPath))
                    {
                        throw new ApplicationException("Input file does not exist: " + inputPath);
                    }
                    input = new NamedText(Path.GetFileName(inputPath), File.ReadAllText(inputPath));
                }

                ServiceInfo service;
                if (ServiceDefinitionUtility.DetectFormat(input) == ServiceDefinitionFormat.Swagger)
                {
                    service = new SwaggerParser {
                        ServiceName = serviceName
                    }.ParseDefinition(input);
                }
                else
                {
                    if (serviceName != null)
                    {
                        throw new ArgsReaderException("--serviceName not supported for FSD input.");
                    }
                    service = new FsdParser().ParseDefinition(input);
                }

                PrepareGenerator(generator, service, outputPath);
                var output = generator.GenerateOutput(service);

                if (SupportsSingleOutput &&
                    !outputPath.EndsWith("/", StringComparison.Ordinal) &&
                    !outputPath.EndsWith("\\", StringComparison.Ordinal) &&
                    !Directory.Exists(outputPath))
                {
                    if (output.NamedTexts.Count > 1)
                    {
                        throw new InvalidOperationException("Multiple outputs not expected.");
                    }

                    if (output.NamedTexts.Count == 1)
                    {
                        var namedText = output.NamedTexts[0];

                        if (outputPath == "-")
                        {
                            System.Console.Write(namedText.Text);
                        }
                        else if (ShouldWriteByteOrderMark(namedText.Name))
                        {
                            File.WriteAllText(outputPath, namedText.Text, s_utf8WithBom);
                        }
                        else
                        {
                            File.WriteAllText(outputPath, namedText.Text);
                        }
                    }
                }
                else
                {
                    var namedTextsToWrite = new List <NamedText>();
                    foreach (var namedText in output.NamedTexts)
                    {
                        string existingFilePath = Path.Combine(outputPath, namedText.Name);
                        if (File.Exists(existingFilePath))
                        {
                            // ignore CR when comparing files
                            if (namedText.Text.Replace("\r", "") != File.ReadAllText(existingFilePath).Replace("\r", ""))
                            {
                                namedTextsToWrite.Add(namedText);
                                if (!isQuiet)
                                {
                                    System.Console.WriteLine("changed " + namedText.Name);
                                }
                            }
                        }
                        else
                        {
                            namedTextsToWrite.Add(namedText);
                            if (!isQuiet)
                            {
                                System.Console.WriteLine("added " + namedText.Name);
                            }
                        }
                    }

                    var namesToDelete = new List <string>();
                    if (shouldClean && output.PatternsToClean.Count != 0)
                    {
                        var directoryInfo = new DirectoryInfo(outputPath);
                        if (directoryInfo.Exists)
                        {
                            foreach (string nameMatchingPattern in FindNamesMatchingPatterns(directoryInfo, output.PatternsToClean))
                            {
                                if (output.NamedTexts.All(x => x.Name != nameMatchingPattern))
                                {
                                    namesToDelete.Add(nameMatchingPattern);
                                    if (!isQuiet)
                                    {
                                        System.Console.WriteLine("removed " + nameMatchingPattern);
                                    }
                                }
                            }
                        }
                    }

                    if (isVerify)
                    {
                        return(namedTextsToWrite.Count != 0 || namesToDelete.Count != 0 ? 1 : 0);
                    }

                    if (!isDryRun)
                    {
                        if (!Directory.Exists(outputPath))
                        {
                            Directory.CreateDirectory(outputPath);
                        }

                        foreach (var namedText in namedTextsToWrite)
                        {
                            string outputFilePath = Path.Combine(outputPath, namedText.Name);

                            string outputFileDirectoryPath = Path.GetDirectoryName(outputFilePath);
                            if (outputFileDirectoryPath != null && outputFileDirectoryPath != outputPath && !Directory.Exists(outputFileDirectoryPath))
                            {
                                Directory.CreateDirectory(outputFileDirectoryPath);
                            }

                            if (ShouldWriteByteOrderMark(namedText.Name))
                            {
                                File.WriteAllText(outputFilePath, namedText.Text, s_utf8WithBom);
                            }
                            else
                            {
                                File.WriteAllText(outputFilePath, namedText.Text);
                            }
                        }

                        foreach (string nameToDelete in namesToDelete)
                        {
                            File.Delete(Path.Combine(outputPath, nameToDelete));
                        }
                    }
                }

                return(0);
            }
            catch (Exception exception)
            {
                if (exception is ApplicationException || exception is ArgsReaderException || exception is ServiceDefinitionException)
                {
                    System.Console.Error.WriteLine(exception.Message);
                    if (exception is ArgsReaderException)
                    {
                        System.Console.Error.WriteLine();
                        WriteUsage();
                    }
                    return(2);
                }
                else
                {
                    System.Console.Error.WriteLine(exception.ToString());
                    return(3);
                }
            }
        }
 public FsdSyncHandler(ILanguageServer router, IDictionary <Uri, ServiceInfo> serviceInfos)
     : base(router, serviceInfos)
 {
     m_parser = new FsdParser();
 }
        /// <summary>
        /// Implements TryParseDefinition.
        /// </summary>
        protected override bool TryParseDefinitionCore(ServiceDefinitionText text, out ServiceInfo?service, out IReadOnlyList <ServiceDefinitionError> errors)
        {
            var isFsd = new FsdParser().TryParseDefinition(text, out service, out errors);

            if (isFsd || text.Name.EndsWith(".fsd", StringComparison.OrdinalIgnoreCase))
            {
                return(isFsd);
            }

            service = null;

            if (string.IsNullOrWhiteSpace(text.Text))
            {
                errors = new[] { new ServiceDefinitionError("Service definition is missing.", new ServiceDefinitionPosition(text.Name, 1, 1)) };
                return(false);
            }

            SwaggerService       swaggerService;
            SwaggerParserContext context;

            if (!s_detectJsonRegex.IsMatch(text.Text))
            {
                // parse YAML
                var yamlDeserializer = new DeserializerBuilder()
                                       .IgnoreUnmatchedProperties()
                                       .WithNamingConvention(new OurNamingConvention())
                                       .Build();
                using (var stringReader = new StringReader(text.Text))
                {
                    try
                    {
                        swaggerService = yamlDeserializer.Deserialize <SwaggerService>(stringReader);
                    }
                    catch (YamlException exception)
                    {
                        var          errorMessage    = exception.InnerException?.Message ?? exception.Message;
                        const string errorStart      = "): ";
                        var          errorStartIndex = errorMessage.IndexOf(errorStart, StringComparison.OrdinalIgnoreCase);
                        if (errorStartIndex != -1)
                        {
                            errorMessage = errorMessage.Substring(errorStartIndex + errorStart.Length);
                        }

                        errors = new[] { new ServiceDefinitionError(errorMessage, new ServiceDefinitionPosition(text.Name, exception.End.Line, exception.End.Column)) };
                        return(false);
                    }
                }

                if (swaggerService == null)
                {
                    errors = new[] { new ServiceDefinitionError("Service definition is missing.", new ServiceDefinitionPosition(text.Name, 1, 1)) };
                    return(false);
                }

                context = SwaggerParserContext.FromYaml(text);
            }
            else
            {
                // parse JSON
                using (var stringReader = new StringReader(text.Text))
                    using (var jsonTextReader = new JsonTextReader(stringReader))
                    {
                        try
                        {
                            swaggerService = JsonSerializer.Create(SwaggerUtility.JsonSerializerSettings).Deserialize <SwaggerService>(jsonTextReader);
                        }
                        catch (JsonException exception)
                        {
                            errors = new[] { new ServiceDefinitionError(exception.Message, new ServiceDefinitionPosition(text.Name, jsonTextReader.LineNumber, jsonTextReader.LinePosition)) };
                            return(false);
                        }

                        context = SwaggerParserContext.FromJson(text);
                    }
            }

            var conversion = SwaggerConversion.Create(swaggerService, ServiceName, context);

            service = conversion.Service;
            errors  = conversion.Errors;
            return(errors.Count == 0);
        }