1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using Mono.Linker.Tests.Cases.Expectations.Assertions;
5 using Mono.Linker.Tests.Extensions;
6 using Mono.Linker.Tests.TestCases;
7 
8 namespace Mono.Linker.Tests.TestCasesRunner {
9 	public class TestCaseSandbox {
10 		protected readonly TestCase _testCase;
11 		protected readonly NPath _directory;
12 
TestCaseSandbox(TestCase testCase)13 		public TestCaseSandbox (TestCase testCase)
14 			: this (testCase, NPath.SystemTemp)
15 		{
16 		}
17 
TestCaseSandbox(TestCase testCase, NPath rootTemporaryDirectory)18 		public TestCaseSandbox (TestCase testCase, NPath rootTemporaryDirectory)
19 			: this (testCase, rootTemporaryDirectory, string.Empty)
20 		{
21 		}
22 
TestCaseSandbox(TestCase testCase, string rootTemporaryDirectory, string namePrefix)23 		public TestCaseSandbox (TestCase testCase, string rootTemporaryDirectory, string namePrefix)
24 			: this (testCase, rootTemporaryDirectory.ToNPath (), namePrefix)
25 		{
26 		}
27 
TestCaseSandbox(TestCase testCase, NPath rootTemporaryDirectory, string namePrefix)28 		public TestCaseSandbox (TestCase testCase, NPath rootTemporaryDirectory, string namePrefix)
29 		{
30 			_testCase = testCase;
31 			var name = string.IsNullOrEmpty (namePrefix) ? "linker_tests" : $"{namePrefix}_linker_tests";
32 			_directory = rootTemporaryDirectory.Combine (name);
33 
34 			_directory.DeleteContents ();
35 
36 			InputDirectory = _directory.Combine ("input").EnsureDirectoryExists ();
37 			OutputDirectory = _directory.Combine ("output").EnsureDirectoryExists ();
38 			ExpectationsDirectory = _directory.Combine ("expectations").EnsureDirectoryExists ();
39 			ResourcesDirectory = _directory.Combine ("resources").EnsureDirectoryExists ();
40 		}
41 
42 		public NPath InputDirectory { get; }
43 
44 		public NPath OutputDirectory { get; }
45 
46 		public NPath ExpectationsDirectory { get; }
47 
48 		public NPath ResourcesDirectory { get; }
49 
50 		public IEnumerable<NPath> SourceFiles {
51 			get { return _directory.Files ("*.cs"); }
52 		}
53 
54 		public IEnumerable<NPath> LinkXmlFiles {
55 			get { return InputDirectory.Files ("*.xml"); }
56 		}
57 
58 		public IEnumerable<NPath> ResourceFiles => ResourcesDirectory.Files ();
59 
Populate(TestCaseMetadaProvider metadataProvider)60 		public virtual void Populate (TestCaseMetadaProvider metadataProvider)
61 		{
62 			_testCase.SourceFile.Copy (_directory);
63 
64 			if (_testCase.HasLinkXmlFile)
65 				_testCase.LinkXmlFile.Copy (InputDirectory);
66 
67 			CopyToInputAndExpectations (GetExpectationsAssemblyPath ());
68 
69 			foreach (var dep in metadataProvider.AdditionalFilesToSandbox ()) {
70 				dep.Source.FileMustExist ().Copy (_directory.Combine (dep.DestinationFileName));
71 			}
72 
73 			foreach (var res in metadataProvider.GetResources ()) {
74 				res.Source.FileMustExist ().Copy (ResourcesDirectory.Combine (res.DestinationFileName));
75 			}
76 
77 			foreach (var compileRefInfo in metadataProvider.GetSetupCompileAssembliesBefore ())
78 			{
79 				var destination = BeforeReferenceSourceDirectoryFor (compileRefInfo.OutputName).EnsureDirectoryExists ();
80 				compileRefInfo.SourceFiles.Copy (destination);
81 			}
82 
83 			foreach (var compileRefInfo in metadataProvider.GetSetupCompileAssembliesAfter ())
84 			{
85 				var destination = AfterReferenceSourceDirectoryFor (compileRefInfo.OutputName).EnsureDirectoryExists ();
86 				compileRefInfo.SourceFiles.Copy (destination);
87 			}
88 		}
89 
GetExpectationsAssemblyPath()90 		private static NPath GetExpectationsAssemblyPath ()
91 		{
92 			return new Uri (typeof (KeptAttribute).Assembly.CodeBase).LocalPath.ToNPath ();
93 		}
94 
CopyToInputAndExpectations(NPath source)95 		protected void CopyToInputAndExpectations (NPath source)
96 		{
97 			source.Copy (InputDirectory);
98 			source.Copy (ExpectationsDirectory);
99 		}
100 
BeforeReferenceSourceDirectoryFor(string outputName)101 		public NPath BeforeReferenceSourceDirectoryFor (string outputName)
102 		{
103 			return _directory.Combine ($"ref_source_before_{Path.GetFileNameWithoutExtension (outputName)}");
104 		}
105 
AfterReferenceSourceDirectoryFor(string outputName)106 		public NPath AfterReferenceSourceDirectoryFor (string outputName)
107 		{
108 			return _directory.Combine ($"ref_source_after_{Path.GetFileNameWithoutExtension (outputName)}");
109 		}
110 	}
111 }