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")); }
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}'"); }
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}'"); }
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}'")); }
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}'"); }
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()"); }
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)); }
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); }
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}'"); }
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)); }
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); }