Пример #1
0
        public void EnumHint_ThrowsOnMemberCountMismatch()
        {
            const string SchemaText =
                @"{
  ""type"": ""object"",
  ""properties"": {
    ""backgroundColor"": {
      ""type"": ""string"",
      ""enum"": [""red"", ""yellow"", ""green""]
    }
  }
}";

            const string HintsText =
                @"{
  ""C.BackgroundColor"": [
    {
      ""kind"": ""EnumHint"",
      ""arguments"": {
        ""typeName"": ""Color"",
        ""memberNames"": [ ""red"", ""yellow"", ""green"", ""blue"" ]
      }
    }
  ]
}";

            Settings.HintDictionary = new HintDictionary(HintsText);
            var generator = new DataModelGenerator(Settings, TestFileSystem.FileSystem);

            JsonSchema schema = SchemaReader.ReadSchema(SchemaText, TestUtil.TestFilePath);

            Action action = () => generator.Generate(schema);

            action.Should().Throw <Exception>().WithMessage("*Color*");
        }
Пример #2
0
        public void ClassNameHint(TestCase test)
        {
            Settings.GenerateEqualityComparers = true;
            Settings.HintDictionary            = new HintDictionary(test.HintsText);
            var generator = new DataModelGenerator(Settings, TestFileSystem.FileSystem);

            JsonSchema schema = SchemaReader.ReadSchema(test.SchemaText, TestUtil.TestFilePath);

            generator.Generate(schema);

            var expectedContentsDictionary = new Dictionary <string, ExpectedContents>
            {
                [Settings.RootClassName] = new ExpectedContents
                {
                    ClassContents         = test.PrimaryClassText,
                    ComparerClassContents = test.PrimaryClassComparerText
                },
                [test.HintedClassName] = new ExpectedContents
                {
                    ClassContents         = test.HintedClassText,
                    ComparerClassContents = test.HintedClassComparerText
                }
            };

            Assert.FileContentsMatchExpectedContents(TestFileSystem, expectedContentsDictionary, Settings.GenerateEqualityComparers);
        }
Пример #3
0
        public void EnumHint(TestCase test)
        {
            Settings.HintDictionary = new HintDictionary(test.HintsText);
            var generator = new DataModelGenerator(Settings, TestFileSystem.FileSystem);

            JsonSchema schema = SchemaReader.ReadSchema(test.SchemaText, TestUtil.TestFilePath);

            Action action = () => generator.Generate(schema);

            if (test.ShouldThrow)
            {
                action.Should().Throw <Exception>();
            }
            else
            {
                action();

                string primaryOutputFilePath = TestFileSystem.MakeOutputFilePath(Settings.RootClassName);
                string enumFilePath          = TestFileSystem.MakeOutputFilePath(test.EnumFileNameStem);

                var expectedOutputFiles = new List <string>
                {
                    primaryOutputFilePath,
                    enumFilePath
                };

                TestFileSystem.Files.Count.Should().Be(expectedOutputFiles.Count);
                TestFileSystem.Files.Should().OnlyContain(key => expectedOutputFiles.Contains(key));

                TestFileSystem[primaryOutputFilePath].Should().Be(test.ClassText);
                TestFileSystem[enumFilePath].Should().Be(test.EnumText);
            }
        }
Пример #4
0
        public void GeneratesInterfaceFromClass(
            string schemaText,
            string hintsText,
            string classText,
            string interfaceText)
        {
            Settings.HintDictionary = new HintDictionary(hintsText);
            var generator = new DataModelGenerator(Settings, TestFileSystem.FileSystem);

            JsonSchema schema = SchemaReader.ReadSchema(schemaText, TestUtil.TestFilePath);

            generator.Generate(schema);

            string primaryOutputFilePath = TestFileSystem.MakeOutputFilePath(Settings.RootClassName);
            string interfaceFilePath     = TestFileSystem.MakeOutputFilePath("I" + Settings.RootClassName);

            var expectedOutputFiles = new List <string>
            {
                primaryOutputFilePath,
                interfaceFilePath
            };

            TestFileSystem.Files.Count.Should().Be(expectedOutputFiles.Count);
            TestFileSystem.Files.Should().OnlyContain(key => expectedOutputFiles.Contains(key));

            TestFileSystem[primaryOutputFilePath].Should().Be(classText);
            TestFileSystem[interfaceFilePath].Should().Be(interfaceText);
        }
Пример #5
0
        public void DictionaryHint(TestCase testCase)
        {
            Settings.GenerateEqualityComparers = true;
            Settings.HintDictionary            = new HintDictionary(testCase.HintsText);
            var generator = new DataModelGenerator(Settings, TestFileSystem.FileSystem);

            JsonSchema schema = SchemaReader.ReadSchema(testCase.SchemaText, TestUtil.TestFilePath);

            generator.Generate(schema);

            var expectedContentsDictionary = new Dictionary <string, ExpectedContents>
            {
                [Settings.RootClassName] = new ExpectedContents
                {
                    ClassContents         = testCase.ExpectedClassText,
                    ComparerClassContents = testCase.ExpectedComparerText
                }
            };

            // We won't bother to compare the contents of the original class (which
            // has no interesting properties), but the assertion method below needs to
            // know how many classes were generated.
            if (testCase.DefinesAdditionalClass)
            {
                expectedContentsDictionary.Add("D", new ExpectedContents());
            }

            Assert.FileContentsMatchExpectedContents(TestFileSystem, expectedContentsDictionary);
        }
Пример #6
0
        /// <summary>
        /// Converts database model to code model (AST).
        /// </summary>
        /// <param name="sqlBuilder">Database-specific <see cref="ISqlBuilder"/> instance.</param>
        /// <param name="dataModel">Database model.</param>
        /// <param name="metadataBuilder">Data model metadata builder.</param>
        /// <param name="modelConverters">Optional AST post-processing converters.</param>
        /// <returns>Code model as collection of code file models.</returns>
        public CodeFile[] GenerateCodeModel(
            ISqlBuilder sqlBuilder,
            DatabaseModel dataModel,
            IMetadataBuilder metadataBuilder,
            params ConvertCodeModelVisitor[] modelConverters)
        {
            var generator = new DataModelGenerator(
                Language,
                dataModel,
                metadataBuilder,
                name => _namingServices.NormalizeIdentifier(_options.DataModel.FindParameterNameOptions, name),
                sqlBuilder,
                _options);

            var files = generator.ConvertToCodeModel();

            foreach (var converter in modelConverters)
            {
                for (var i = 0; i < files.Length; i++)
                {
                    files[i] = (CodeFile)converter.Visit(files[i]);
                }
            }

            return(files);
        }
Пример #7
0
        public static void Main(string[] args)
        {
            var host = CreateHostBuilder(args).Build();

            //2. Find the service layer within our scope.
            using (var scope = host.Services.CreateScope())
            {
                var services = scope.ServiceProvider;
                services.GetRequiredService <MortgageCalculatorDbContext>();
                DataModelGenerator.Initialize(services);
            }
            host.Run();
        }
Пример #8
0
        protected MapConfig Build(string workingFolder,
                                  ProjectSettings settings,
                                  ComplexType baseModel,
                                  ISchemaDescriptor schema,
                                  IDictionary <string, string> entityRenames,
                                  string mapFileName)
        {
            var rwords = Mssq2008Dialect.SqlServerReservedWords.Split(new string[] { " ", "\n", "," }, StringSplitOptions.RemoveEmptyEntries);

            schema.ProjectSettings = settings;
            var generator = new DataModelGenerator(schema, new NameTransformerFactory(settings),
                                                   new DefaultTableNameAbbreviator(rwords));

            MapConfig builder;

            if (baseModel != null)
            {
                builder = generator.GenerateMap(settings, entityRenames, baseModel);
            }
            else
            {
                builder = generator.GenerateMap(settings, entityRenames);
            }

            CreateFolderIfNotExist(workingFolder);

            string mapfile;

            if (!Path.IsPathRooted(mapFileName))
            {
                mapfile = Path.Combine(workingFolder, mapFileName);
            }
            else
            {
                mapfile = mapFileName;
            }

            builder.Save(mapfile, true);
            return(builder);
        }
Пример #9
0
        public void EnumHint_DoesNotThrowWhenCountMismatchCheckIsDisabled()
        {
            const string SchemaText =
                @"{
  ""type"": ""object"",
  ""properties"": {
    ""backgroundColor"": {
      ""type"": ""string"",
      ""enum"": [""red"", ""yellow"", ""green""]
    }
  }
}";

            const string HintsText =
                @"{
  ""C.BackgroundColor"": [
    {
      ""kind"": ""EnumHint"",
      ""arguments"": {
        ""typeName"": ""Color"",
        ""memberNames"": [ ""red"", ""yellow"", ""green"", ""blue"" ],
        ""allowMemberCountMismatch"": true
      }
    }
  ]
}";

            Settings.HintDictionary = new HintDictionary(HintsText);
            var generator = new DataModelGenerator(Settings, TestFileSystem.FileSystem);

            JsonSchema schema = SchemaReader.ReadSchema(SchemaText, TestUtil.TestFilePath);

            Action action = () => generator.Generate(schema);

            action.Should().NotThrow();
        }
Пример #10
0
        protected void RunHintTestCase(HintTestCase testCase)
        {
            string actual = null;
            Action action = () =>
            {
                Settings.HintDictionary = new HintDictionary(testCase.HintsText);
                var generator = new DataModelGenerator(Settings, TestFileSystem.FileSystem);

                JsonSchema schema = SchemaReader.ReadSchema(testCase.SchemaText, TestUtil.TestFilePath);

                actual = generator.Generate(schema);
            };

            if (testCase.ShouldThrow)
            {
                action.Should().Throw <Exception>()
                .WithMessage('*' + (testCase.ExpectedErrorMessage ?? string.Empty) + '*');
            }
            else
            {
                action();
                actual.Should().Be(testCase.ExpectedOutput);
            }
        }
Пример #11
0
        static int Main(String[] args)
        {
            // These are the parameters that are parsed out of the command line.
            String inputFilePath   = String.Empty;
            String outputFileName  = String.Empty;
            String targetNamespace = "DefaultNamespace";

            try
            {
                // The command line parser is driven by different states that are triggered by the flags read.  Unless a flag has been parsed, the command line
                // parser assumes that it's reading the file name from the command line.
                ArgumentState argumentState = ArgumentState.InputFileName;

                // Parse the command line for arguments.
                foreach (String argument in args)
                {
                    // Use the dictionary to transition from one state to the next based on the input parameters.
                    ArgumentState nextArgumentState;
                    if (ClientCompiler.argumentStates.TryGetValue(argument, out nextArgumentState))
                    {
                        argumentState = nextArgumentState;
                        continue;
                    }

                    // The parsing state will determine which variable is read next.
                    switch (argumentState)
                    {
                    case ArgumentState.InputFileName:

                        // Expand the environment variables so that paths don't need to be absolute.
                        inputFilePath = Environment.ExpandEnvironmentVariables(argument);

                        // The output name defaults to the input file name with a new extension.
                        outputFileName = String.Format("{0}.cs", Path.GetFileNameWithoutExtension(inputFilePath));

                        break;

                    case ArgumentState.OutputFileName:

                        // Expand the environment variables so that paths don't need to be absolute.
                        outputFileName = Environment.ExpandEnvironmentVariables(argument);
                        break;

                    case ArgumentState.TargetNamespace:

                        // This is the namespace that is used to create the target data model.
                        targetNamespace = argument;
                        break;
                    }

                    // The default state is to look for the input file name on the command line.
                    argumentState = ArgumentState.InputFileName;
                }

                // This will read the input XML schema into a large buffer.
                String fileContents;
                using (StreamReader streamReader = new StreamReader(inputFilePath))
                    fileContents = streamReader.ReadToEnd();

                // This next step simulates the calling convension used by a custom tool, which is to say it uses unmanaged code.  The progress indicator is used
                // to provide feedback, to either the IDE or the command line, about how far along the compilation is.  Note that the calling interface is from
                // unmanaged-code to managed code, the way you would expect the IDE to call the generator, so we create an unmanaged buffer pointer for the results.
                IntPtr[]           buffer = new IntPtr[1];
                UInt32             bufferSize;
                DataModelGenerator dataModelGenerator = new DataModelGenerator();
                dataModelGenerator.Generate(inputFilePath, fileContents, targetNamespace, buffer, out bufferSize, new ProgressIndicator());

                // Once the buffer of source code is generated, it is copied back out of the unmanaged buffers and written to the output file.
                Byte[] outputBuffer = new byte[bufferSize];
                Marshal.Copy(buffer[0], outputBuffer, 0, Convert.ToInt32(bufferSize));
                using (StreamWriter streamWriter = new StreamWriter(outputFileName))
                    streamWriter.Write(Encoding.UTF8.GetString(outputBuffer));
            }
            catch (Exception exception)
            {
                // This will catch any generic errors and dump them to the console.
                Console.WriteLine(exception.Message);
            }

            // The execution at this point was a success.
            return(0);
        }
Пример #12
0
        public void EnumHint_WildCard()
        {
            const string SchemaText =
                @"{
  ""type"": ""object"",
  ""properties"": {
    ""def1Prop"": {
      ""$ref"": ""#/definitions/def1""
    },
    ""def2Prop"": {
      ""$ref"": ""#/definitions/def2""
    }
  },
  ""definitions"": {
    ""def1"": {
      ""type"": ""object"",
      ""properties"": {
        ""backgroundColor"": {
          ""type"": ""string"",
          ""enum"": [ ""red"", ""green"", ""blue"" ]
        }
      }
    },
    ""def2"": {
      ""type"": ""object"",
      ""properties"": {
        ""backgroundColor"": {
          ""type"": ""string"",
          ""enum"": [ ""red"", ""green"", ""blue"" ]
        }
      }
    }
  }
}";
            const string HintsText =
                @"{
  ""*.BackgroundColor"": [
    {
      ""kind"": ""EnumHint"",
      ""arguments"": {
        ""typeName"": ""Color""
      }
    }
  ]
}";

            const string RootClassText = @"using System;
using System.CodeDom.Compiler;
using System.Runtime.Serialization;

namespace N
{
    [DataContract]
    [GeneratedCode(""Microsoft.Json.Schema.ToDotNet"", """ + VersionConstants.FileVersion + @""")]
    public partial class C
    {
        [DataMember(Name = ""def1Prop"", IsRequired = false, EmitDefaultValue = false)]
        public Def1 Def1Prop { get; set; }
        [DataMember(Name = ""def2Prop"", IsRequired = false, EmitDefaultValue = false)]
        public Def2 Def2Prop { get; set; }
    }
}";
            const string Def1ClassText =
                @"using System;
using System.CodeDom.Compiler;
using System.Runtime.Serialization;

namespace N
{
    [DataContract]
    [GeneratedCode(""Microsoft.Json.Schema.ToDotNet"", """ + VersionConstants.FileVersion + @""")]
    public partial class Def1
    {
        [DataMember(Name = ""backgroundColor"", IsRequired = false, EmitDefaultValue = false)]
        public Color BackgroundColor { get; set; }
    }
}";
            const string Def2ClassText =
                @"using System;
using System.CodeDom.Compiler;
using System.Runtime.Serialization;

namespace N
{
    [DataContract]
    [GeneratedCode(""Microsoft.Json.Schema.ToDotNet"", """ + VersionConstants.FileVersion + @""")]
    public partial class Def2
    {
        [DataMember(Name = ""backgroundColor"", IsRequired = false, EmitDefaultValue = false)]
        public Color BackgroundColor { get; set; }
    }
}";

            const string EnumText =
                @"using System.CodeDom.Compiler;

namespace N
{
    [GeneratedCode(""Microsoft.Json.Schema.ToDotNet"", """ + VersionConstants.FileVersion + @""")]
    public enum Color
    {
        Red,
        Green,
        Blue
    }
}";

            Settings.HintDictionary = new HintDictionary(HintsText);
            var generator = new DataModelGenerator(Settings, TestFileSystem.FileSystem);

            JsonSchema schema = SchemaReader.ReadSchema(SchemaText, TestUtil.TestFilePath);

            generator.Generate(schema);

            string primaryOutputFilePath = TestFileSystem.MakeOutputFilePath(Settings.RootClassName);
            string enumFilePath          = TestFileSystem.MakeOutputFilePath("Color");
            string def1FilePath          = TestFileSystem.MakeOutputFilePath("Def1");
            string def2FilePath          = TestFileSystem.MakeOutputFilePath("Def2");

            var expectedOutputFiles = new List <string>
            {
                primaryOutputFilePath,
                enumFilePath,
                def1FilePath,
                def2FilePath
            };

            TestFileSystem.Files.Count.Should().Be(expectedOutputFiles.Count);
            TestFileSystem.Files.Should().OnlyContain(key => expectedOutputFiles.Contains(key));

            TestFileSystem[primaryOutputFilePath].Should().Be(RootClassText);
            TestFileSystem[enumFilePath].Should().Be(EnumText);
            TestFileSystem[def1FilePath].Should().Be(Def1ClassText);
            TestFileSystem[def2FilePath].Should().Be(Def2ClassText);
        }
Пример #13
0
        public void DictionaryHint_WildCard()
        {
            const string SchemaText =
                @"{
  ""type"": ""object"",
  ""properties"": {
    ""def1Prop"": {
      ""$ref"": ""#/definitions/def1""
    },
    ""def2Prop"": {
      ""$ref"": ""#/definitions/def2""
    }
  },
  ""definitions"": {
    ""def1"": {
      ""type"": ""object"",
      ""properties"": {
        ""properties"": {
          ""type"": ""object""
        }
      }
    },
    ""def2"": {
      ""type"": ""object"",
      ""properties"": {
        ""properties"": {
          ""type"": ""object"",
        }
      }
    }
  }
}";

            const string HintsText =
                @"{
  ""*.Properties"": [
    {
      ""kind"": ""DictionaryHint"",
      ""arguments"": {
        ""keyTypeName"": ""Uri""
      }
    }
  ]
}";

            const string RootClassText =
                @"using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace N
{
    [DataContract]
    [GeneratedCode(""Microsoft.Json.Schema.ToDotNet"", """ + VersionConstants.FileVersion + @""")]
    public partial class C
    {
        public static IEqualityComparer<C> ValueComparer => CEqualityComparer.Instance;

        public bool ValueEquals(C other) => ValueComparer.Equals(this, other);
        public int ValueGetHashCode() => ValueComparer.GetHashCode(this);

        [DataMember(Name = ""def1Prop"", IsRequired = false, EmitDefaultValue = false)]
        public Def1 Def1Prop { get; set; }
        [DataMember(Name = ""def2Prop"", IsRequired = false, EmitDefaultValue = false)]
        public Def2 Def2Prop { get; set; }
    }
}";

            const string Def1ClassText =
                @"using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace N
{
    [DataContract]
    [GeneratedCode(""Microsoft.Json.Schema.ToDotNet"", """ + VersionConstants.FileVersion + @""")]
    public partial class Def1
    {
        public static IEqualityComparer<Def1> ValueComparer => Def1EqualityComparer.Instance;

        public bool ValueEquals(Def1 other) => ValueComparer.Equals(this, other);
        public int ValueGetHashCode() => ValueComparer.GetHashCode(this);

        [DataMember(Name = ""properties"", IsRequired = false, EmitDefaultValue = false)]
        public IDictionary<Uri, string> Properties { get; set; }
    }
}";

            const string Def2ClassText =
                @"using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace N
{
    [DataContract]
    [GeneratedCode(""Microsoft.Json.Schema.ToDotNet"", """ + VersionConstants.FileVersion + @""")]
    public partial class Def2
    {
        public static IEqualityComparer<Def2> ValueComparer => Def2EqualityComparer.Instance;

        public bool ValueEquals(Def2 other) => ValueComparer.Equals(this, other);
        public int ValueGetHashCode() => ValueComparer.GetHashCode(this);

        [DataMember(Name = ""properties"", IsRequired = false, EmitDefaultValue = false)]
        public IDictionary<Uri, string> Properties { get; set; }
    }
}";

            Settings.GenerateEqualityComparers = true;
            Settings.HintDictionary            = new HintDictionary(HintsText);
            var generator = new DataModelGenerator(Settings, TestFileSystem.FileSystem);

            JsonSchema schema = SchemaReader.ReadSchema(SchemaText, TestUtil.TestFilePath);

            generator.Generate(schema);

            var expectedContentsDictionary = new Dictionary <string, ExpectedContents>
            {
                [Settings.RootClassName] = new ExpectedContents
                {
                    ClassContents         = RootClassText,
                    ComparerClassContents = null // Don't bother to compare the comparer class contents.
                },

                ["Def1"] = new ExpectedContents
                {
                    ClassContents         = Def1ClassText,
                    ComparerClassContents = null
                },

                ["Def2"] = new ExpectedContents
                {
                    ClassContents         = Def2ClassText,
                    ComparerClassContents = null
                }
            };

            Assert.FileContentsMatchExpectedContents(TestFileSystem, expectedContentsDictionary);
        }