Пример #1
0
        public async Task SaveSourceFiles_GivenSourceFiles_CompressesAndSaves()
        {
            //Arrange
            IEnumerable <SourceFile> sourceFiles = new[]
            {
                new SourceFile {
                    FileName = "project.vbproj", SourceCode = "<Project Sdk=\"Microsoft.NET.Sdk\"><PropertyGroup><TargetFramework>netcoreapp2.0</TargetFramework></PropertyGroup></Project>"
                },
                new SourceFile {
                    FileName = "ExampleClass.vb", SourceCode = "Public Class ExampleClass\nPublic Property ProviderType() As String\nEnd Class"
                },
                new SourceFile {
                    FileName = "Calculation.vb", SourceCode = "code"
                }
            };

            ISourceFileRepository sourceFileRepository = CreateSourceFileRepository();

            SourceCodeService sourceCodeService = CreateSourceCodeService(sourceFileRepository);

            //Act
            await sourceCodeService.SaveSourceFiles(sourceFiles, specificationId, SourceCodeType.Release);

            //Assert
            await
            sourceFileRepository
            .Received(1)
            .SaveSourceFiles(Arg.Any <byte[]>(), Arg.Is(specificationId), Arg.Is("release"));
        }
Пример #2
0
        public void GetAssembly_GivenNullStreamReturned_ThrowsException()
        {
            //Arrange
            BuildProject buildProject = new BuildProject
            {
                SpecificationId = specificationId,
            };

            ISourceFileRepository sourceFileRepository = CreateSourceFileRepository();

            sourceFileRepository
            .DoesAssemblyExist(Arg.Is(specificationId))
            .Returns(true);

            sourceFileRepository
            .GetAssembly(Arg.Is(specificationId))
            .Returns((Stream)null);

            ILogger logger = CreateLogger();

            SourceCodeService sourceCodeService = CreateSourceCodeService(sourceFileRepository, logger);

            //Act
            Func <Task> test = async() => await sourceCodeService.GetAssembly(buildProject);

            //Assert
            test
            .Should()
            .ThrowExactly <Exception>()
            .Which
            .Message
            .Should()
            .Be($"Failed to get assembly for specification id: '{specificationId}'");
        }
Пример #3
0
        public async Task SaveAssembly_GivenAssemblyAndSabeSuccessful_LogsSuccess()
        {
            //Arrange
            BuildProject buildProject = new BuildProject
            {
                SpecificationId = specificationId,
                Build           = new Build
                {
                    Assembly = new byte[100]
                }
            };

            ISourceFileRepository sourceFileRepository = CreateSourceFileRepository();

            ILogger logger = CreateLogger();

            SourceCodeService sourceFileService = CreateSourceCodeService(sourceFileRepository, logger);

            //Act
            await sourceFileService.SaveAssembly(buildProject);

            //Assert
            logger
            .Received(1)
            .Information($"Saved assembly for specification id: '{buildProject.SpecificationId}'");
        }
Пример #4
0
        public void SaveAssembly_GivenAssemblyButFailsToSave_ThrowsException()
        {
            //Arrange
            BuildProject buildProject = new BuildProject
            {
                SpecificationId = specificationId,
                Build           = new Build
                {
                    Assembly = new byte[100]
                }
            };

            ISourceFileRepository sourceFileRepository = CreateSourceFileRepository();

            sourceFileRepository.When(x => x.SaveAssembly(Arg.Is(buildProject.Build.Assembly), Arg.Is(buildProject.SpecificationId)))
            .Do(x => { throw new Exception(); });

            ILogger logger = CreateLogger();

            SourceCodeService sourceFileService = CreateSourceCodeService(sourceFileRepository, logger);

            //Act
            Func <Task> test = async() => await sourceFileService.SaveAssembly(buildProject);

            //Assert
            test
            .Should()
            .ThrowExactly <Exception>();

            logger
            .Received(1)
            .Error(Arg.Any <Exception>(), Arg.Is($"Failed to save assembly for specification id '{buildProject.SpecificationId}'"));
        }
Пример #5
0
        public void SaveAssembly_GivenBuildProjectDoesntNotContainAssembly_ThrowsArgumentException()
        {
            //Arrange
            BuildProject buildProject = new BuildProject
            {
                SpecificationId = specificationId,
                Build           = new Build()
            };

            ISourceFileRepository sourceFileRepository = CreateSourceFileRepository();

            ILogger logger = CreateLogger();

            SourceCodeService sourceFileService = CreateSourceCodeService(sourceFileRepository, logger);

            //Act
            Func <Task> test = async() => await sourceFileService.SaveAssembly(buildProject);

            //Assert
            test
            .Should()
            .ThrowExactly <ArgumentException>()
            .Which
            .Message
            .Should()
            .Be($"Assembly not present on build project for specification id: '{buildProject.SpecificationId}'");
        }
Пример #6
0
        public void CompileBuildProject_WhenBuildingCalculation_ThenCompilationUsesSourceCodeName()
        {
            // Arrange
            string             specificationId = "test-spec1";
            List <Calculation> calculations    = new List <Calculation>
            {
                new Calculation
                {
                    Id             = "calcId1",
                    Name           = "calc 1",
                    SourceCodeName = "differentCalcName",
                    Description    = "test calc",
                    AllocationLine = new Common.Models.Reference {
                        Id = "alloc1", Name = "alloc one"
                    },
                    CalculationSpecification = new Common.Models.Reference {
                        Id = "calcSpec1", Name = "calc spec 1"
                    },
                    Policies = new List <Common.Models.Reference>
                    {
                        new Common.Models.Reference {
                            Id = "policy1", Name = "policy one"
                        }
                    },
                    Current = new CalculationVersion
                    {
                        SourceCode = "return 10"
                    }
                }
            };

            SourceCodeService sourceCodeService = CreateServiceWithRealCompiler();

            BuildProject buildProject = new BuildProject
            {
                SpecificationId = specificationId,
                Id   = Guid.NewGuid().ToString(),
                Name = specificationId
            };

            CompilerOptions compilerOptions = new CompilerOptions();

            // Act
            Build build = sourceCodeService.Compile(buildProject, calculations, compilerOptions);

            // Assert
            build.Success.Should().BeTrue();

            string calcSourceCode = build.SourceFiles.First(s => s.FileName == "Calculations.vb").SourceCode;

            calcSourceCode.Should().Contain($"Dim differentCalcName As Func(Of decimal?) = nothing");
            calcSourceCode.Should().NotContain($"Dim calc1 As Func(Of decimal?) = nothing");
            calcSourceCode.Should().Contain($"differentCalcName()");
            calcSourceCode.Should().NotContain($"calc1()");
        }
        public void CompileBuildProject_WhenBuildingCalculation_ThenCompilationUsesSourceCodeName(CalculationDataType calculationDataType, string sourceCode, string expectedType)
        {
            // Arrange
            string             specificationId = "test-spec1";
            List <Calculation> calculations    = new List <Calculation>
            {
                new Calculation
                {
                    Id      = "calcId1",
                    Current = new CalculationVersion
                    {
                        SourceCode            = sourceCode,
                        Name                  = "calc 1",
                        SourceCodeName        = "differentCalcName",
                        Description           = "test calc",
                        DataType              = calculationDataType,
                        AllowedEnumTypeValues = calculationDataType == CalculationDataType.Enum ? new List <string>()
                        {
                            "T1", "T2", "T3"
                        } : null
                    }
                }
            };

            SourceCodeService sourceCodeService = CreateServiceWithRealCompiler();

            BuildProject buildProject = new BuildProject
            {
                SpecificationId = specificationId,
                Id           = Guid.NewGuid().ToString(),
                Name         = specificationId,
                FundingLines = new Dictionary <string, Funding>()
            };

            CompilerOptions compilerOptions = new CompilerOptions();

            // Act
            Build build = sourceCodeService.Compile(buildProject, calculations, compilerOptions);

            // Assert
            build.Success.Should().BeTrue();

            string calcSourceCode = build.SourceFiles.First(s => s.FileName == "Calculations.vb").SourceCode;

            calcSourceCode.Should().Contain($"Public differentCalcName As Func(Of {expectedType}) = Nothing");
            calcSourceCode.Should().NotContain($"Public calc1 As Func(Of {expectedType}) = Nothing");
            calcSourceCode.Should().Contain($"differentCalcName()");
            calcSourceCode.Should().NotContain($"calc1()");
        }
Пример #8
0
        public void Compile_ErrorThrown_ReturnsErrorAsCompilerMessage()
        {
            //Arrange
            BuildProject buildProject = new BuildProject {
                SpecificationId = "3456"
            };
            IEnumerable <Calculation> calculations = new List <Calculation>();

            string errorMessage = "The sky is red, I don't understand";

            ISourceFileGenerator sourceFileGenerator = Substitute.For <ISourceFileGenerator>();

            sourceFileGenerator
            .GenerateCode(buildProject, calculations, Arg.Any <CompilerOptions>())
            .Throws(new Exception(errorMessage));

            ISourceFileGeneratorProvider sourceFileGeneratorProvider = CreateSourceFileGeneratorProvider();

            sourceFileGeneratorProvider
            .CreateSourceFileGenerator(TargetLanguage.VisualBasic)
            .Returns(sourceFileGenerator);

            SourceCodeService sourceCodeService = CreateSourceCodeService(sourceFileGeneratorProvider: sourceFileGeneratorProvider);

            //Act
            Build result = sourceCodeService.Compile(buildProject, calculations);

            //Assert
            result.CompilerMessages.Count
            .Should()
            .Be(1);
            result.CompilerMessages.Count(x => x.Message == errorMessage && x.Severity == Severity.Error)
            .Should()
            .Be(1);

            sourceFileGenerator
            .Received(1)
            .GenerateCode(buildProject,
                          calculations,
                          Arg.Is <CompilerOptions>(x => x.SpecificationId == buildProject.SpecificationId && !x.OptionStrictEnabled));
        }
Пример #9
0
        public async Task GetAssembly_GivenStreamReturned_ReturnsAssembly()
        {
            //Arrange
            BuildProject buildProject = new BuildProject
            {
                SpecificationId = specificationId,
            };

            ISourceFileRepository sourceFileRepository = CreateSourceFileRepository();

            sourceFileRepository
            .DoesAssemblyExist(Arg.Is(specificationId))
            .Returns(true);

            Stream stream = new MemoryStream(new byte[100]);

            sourceFileRepository
            .GetAssembly(Arg.Is(specificationId))
            .Returns(stream);

            ILogger logger = CreateLogger();

            SourceCodeService sourceCodeService = CreateSourceCodeService(sourceFileRepository, logger);

            //Act
            byte[] assembly = await sourceCodeService.GetAssembly(buildProject);

            //Assert
            assembly
            .Should()
            .NotBeNull();

            assembly
            .Length
            .Should()
            .Be(100);
        }
Пример #10
0
        public async Task SaveSourceFiles_GivenEmptySourceFiles_LogsAndDoesNotSave()
        {
            //Arrange
            IEnumerable <SourceFile> sourceFiles = Enumerable.Empty <SourceFile>();

            ISourceFileRepository sourceFileRepository = CreateSourceFileRepository();

            ILogger logger = CreateLogger();

            SourceCodeService sourceCodeService = CreateSourceCodeService(sourceFileRepository, logger);

            //Act
            await sourceCodeService.SaveSourceFiles(sourceFiles, specificationId, SourceCodeType.Preview);

            //Assert
            await
            sourceFileRepository
            .DidNotReceive()
            .SaveSourceFiles(Arg.Any <byte[]>(), Arg.Is(specificationId), Arg.Is("preview"));

            logger
            .Received(1)
            .Error($"Failed to compress source files for specification id: '{specificationId}'");
        }
Пример #11
0
        public void Compile_GivenStringCompareInCodeAndAggregatesIsEnabledAndCalculationAggregateFunctionsFound_CompilesCodeAndReturnsOk()
        {
            //Arrange
            string stringCompareCode = "Public Class TestClass\nPublic Property E1 As ExampleClass\nPublic Function TestFunction As String\nIf E1.ProviderType = \"goodbye\" Then\nReturn Sum(Calc1)\nElse Return \"no\"\nEnd If\nEnd Function\nEnd Class";

            Calculation calculation = new Calculation
            {
                Id              = calculationId,
                BuildProjectId  = buildProjectId,
                Current         = new CalculationVersion(),
                SpecificationId = specificationId,
                Name            = "TestFunction"
            };

            IEnumerable <Calculation> calculations = new List <Calculation>()
            {
                calculation
            };

            BuildProject buildProject = new BuildProject
            {
                SpecificationId = specificationId
            };

            ILogger logger = CreateLogger();

            List <SourceFile> sourceFiles = new List <SourceFile>
            {
                new SourceFile {
                    FileName = "project.vbproj", SourceCode = "<Project Sdk=\"Microsoft.NET.Sdk\"><PropertyGroup><TargetFramework>netcoreapp2.0</TargetFramework></PropertyGroup></Project>"
                },
                new SourceFile {
                    FileName = "ExampleClass.vb", SourceCode = "Public Class ExampleClass\nPublic Property ProviderType() As String\nEnd Class"
                },
                new SourceFile {
                    FileName = "Calculation.vb", SourceCode = stringCompareCode
                }
            };

            Build build = new Build
            {
                Success     = true,
                SourceFiles = sourceFiles
            };

            Dictionary <string, string> sourceCodes = new Dictionary <string, string>()
            {
                { "TestFunction", stringCompareCode },
                { "Calc1", "return 1" }
            };

            CompilerOptions compilerOptions = new CompilerOptions();

            ISourceFileGenerator sourceFileGenerator = Substitute.For <ISourceFileGenerator>();

            sourceFileGenerator
            .GenerateCode(Arg.Is(buildProject), Arg.Is(calculations), compilerOptions)
            .Returns(sourceFiles);

            ISourceFileGeneratorProvider sourceFileGeneratorProvider = CreateSourceFileGeneratorProvider();

            sourceFileGeneratorProvider
            .CreateSourceFileGenerator(Arg.Any <TargetLanguage>())
            .Returns(sourceFileGenerator);

            ICompiler compiler = CreateCompiler();

            ICompilerFactory compilerFactory = CreateCompilerFactory(compiler, sourceFiles);

            SourceCodeService sourceCodeService = CreateSourceCodeService(sourceFileGeneratorProvider: sourceFileGeneratorProvider, compilerFactory: compilerFactory);

            //Act
            Build buildResult = sourceCodeService.Compile(buildProject, calculations, compilerOptions);

            //Assert
            compiler
            .Received(1)
            .GenerateCode(Arg.Is <List <SourceFile> >(m => m.Count == 3));
        }
Пример #12
0
        public async Task GetAssembly_GivenAssemblyDoesNotExist_CompilesNewAssembly()
        {
            //Arrange
            BuildProject buildProject = new BuildProject
            {
                SpecificationId = specificationId,
            };

            Calculation calculation = new Calculation
            {
                Id              = calculationId,
                BuildProjectId  = buildProjectId,
                Current         = new CalculationVersion(),
                SpecificationId = specificationId,
                Name            = "TestFunction"
            };

            IEnumerable <Calculation> calculations = new List <Calculation>()
            {
                calculation
            };

            ISourceFileRepository sourceFileRepository = CreateSourceFileRepository();

            sourceFileRepository
            .DoesAssemblyExist(Arg.Is(specificationId))
            .Returns(false);

            List <SourceFile> sourceFiles = new List <SourceFile>
            {
                new SourceFile {
                    FileName = "project.vbproj", SourceCode = "<Project Sdk=\"Microsoft.NET.Sdk\"><PropertyGroup><TargetFramework>netcoreapp2.0</TargetFramework></PropertyGroup></Project>"
                },
                new SourceFile {
                    FileName = "ExampleClass.vb", SourceCode = "Public Class ExampleClass\nPublic Property ProviderType() As String\nEnd Class"
                },
                new SourceFile {
                    FileName = "Calculation.vb", SourceCode = "code"
                }
            };

            buildProject.Build = new Build
            {
                SourceFiles = sourceFiles,
            };

            Build newBuild = new Build
            {
                SourceFiles = sourceFiles,
                Assembly    = new byte[100]
            };

            ISourceFileGenerator sourceFileGenerator = Substitute.For <ISourceFileGenerator>();

            sourceFileGenerator
            .GenerateCode(Arg.Is(buildProject), Arg.Any <IEnumerable <Calculation> >(), Arg.Any <CompilerOptions>())
            .Returns(sourceFiles);

            ISourceFileGeneratorProvider sourceFileGeneratorProvider = CreateSourceFileGeneratorProvider();

            sourceFileGeneratorProvider
            .CreateSourceFileGenerator(Arg.Any <TargetLanguage>())
            .Returns(sourceFileGenerator);

            ICompiler compiler = CreateCompiler();

            compiler
            .GenerateCode(Arg.Any <List <SourceFile> >())
            .Returns(newBuild);

            ICompilerFactory compilerFactory = CreateCompilerFactory(compiler, sourceFiles);

            SourceCodeService sourceCodeService = CreateSourceCodeService(sourceFileGeneratorProvider: sourceFileGeneratorProvider, compilerFactory: compilerFactory);

            //Act
            byte[] assembly = await sourceCodeService.GetAssembly(buildProject);

            //Assert
            assembly
            .Should()
            .NotBeNull();

            assembly
            .Length
            .Should()
            .Be(100);
        }