コード例 #1
0
        public void LinkedServerProjectCache_Ctor()
        {
            LinkedServerProjectCache cache;

            ConsoleLogger logger = new ConsoleLogger();
            using (ProjectFileReader projectFileReader = new ProjectFileReader(logger))
            {
                // Null project  file throws
                ExceptionHelper.ExpectArgumentNullExceptionStandard(() => cache = new LinkedServerProjectCache(null, "breadCrumb", logger, projectFileReader), "rootProjectPath");
                ExceptionHelper.ExpectArgumentNullExceptionStandard(() => cache = new LinkedServerProjectCache(String.Empty, "breadCrumb", logger, projectFileReader), "rootProjectPath");

                // Null logger throws
                ExceptionHelper.ExpectArgumentNullExceptionStandard(() => cache = new LinkedServerProjectCache("proj", null, logger, projectFileReader), "historyFilePath");
                ExceptionHelper.ExpectArgumentNullExceptionStandard(() => cache = new LinkedServerProjectCache("proj", String.Empty, logger, projectFileReader), "historyFilePath");

                // Null logger throws
                ExceptionHelper.ExpectArgumentNullExceptionStandard(() => cache = new LinkedServerProjectCache("proj", "breadCrumb", null, projectFileReader), "logger");

                // Null projectFileLogger throws
                ExceptionHelper.ExpectArgumentNullExceptionStandard(() => cache = new LinkedServerProjectCache("proj", "breadCrumb", logger, null), "projectFileReader");

                // Valid ctor succeeds
                cache = new LinkedServerProjectCache("proj", "breadCrumb", logger, projectFileReader);
            }
        }
コード例 #2
0
        public void ProjectFileReader_Bad_Project_File_Warns()
        {
            ConsoleLogger logger = new ConsoleLogger();
            using (ProjectFileReader projectFileReader = new ProjectFileReader(logger))
            {
                string badProjectPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".csproj");
                File.WriteAllText(badProjectPath, "neener neener");

                try
                {
                    projectFileReader.LoadProject(badProjectPath);

                    // Simulate the exception so we get the exact text
                    string warningMessage = null;
                    try
                    {
                        Engine engine = new Engine();
                        Project project = new Project(engine);
                        project.Load(badProjectPath);

                    }
                    catch (InvalidProjectFileException ipfe)
                    {
                        warningMessage = string.Format(CultureInfo.CurrentCulture, Resource.Failed_To_Open_Project, badProjectPath, ipfe.Message);
                    }

                    TestHelper.AssertContainsWarnings(logger, new string[] { warningMessage });
                }
                finally
                {
                    File.Delete(badProjectPath);
                }
            }
        }
コード例 #3
0
        public void ProjectFileReader_Ctor()
        {
            ConsoleLogger logger = new ConsoleLogger();

            ExceptionHelper.ExpectArgumentNullExceptionStandard(() => new ProjectFileReader(null), "logger");

            using (ProjectFileReader projectFileReader = new ProjectFileReader(logger))
            {
            }
        }
コード例 #4
0
 public void ProjectFileReader_Dispose_Multiple()
 {
     ConsoleLogger logger = new ConsoleLogger();
     ProjectFileReader projectFileReader;
     using (projectFileReader = new ProjectFileReader(logger))
     {
     }
     projectFileReader.Dispose();
     projectFileReader.Dispose();
     System.GC.Collect();
     System.GC.WaitForPendingFinalizers();
     projectFileReader.Dispose();
 }
コード例 #5
0
        public void ProjectSourceFileCache_Indexer()
        {
            ConsoleLogger logger = new ConsoleLogger();
            using (ProjectFileReader projectFileReader = new ProjectFileReader(logger))
            {

                ProjectSourceFileCache cache = new ProjectSourceFileCache("proj", "breadCrumb", logger, projectFileReader);

                // First access allocates empty instance
                Assert.IsNotNull(cache.SourceFilesByProject);
                Assert.AreEqual(0, cache.SourceFilesByProject.Count, "Expected empty cache");

                // Indexer setter can be called
                cache["proj"] = new string[] { "a", "b", "c" };

                // Which invalidates the currency of the cache
                Assert.IsFalse(cache.IsFileCacheCurrent, "Adding to the cache should have marked the file cache as out of date.");

                // And indexer getter returns the inputs
                IEnumerable<string> files = cache["proj"];
                Assert.IsNotNull(files);
                Assert.AreEqual(3, files.Count());
                Assert.IsTrue(files.Contains("a"));
                Assert.IsTrue(files.Contains("b"));
                Assert.IsTrue(files.Contains("c"));

                // Cache is case insensitive.  Should overwrite entry differing only in case
                cache["PrOj"] = new string[] { "d", "e" };
                Assert.AreEqual(1, cache.SourceFilesByProject.Count, "Key differing only in case should have overwritten existing one");
                files = cache["PrOj"];
                Assert.IsNotNull(files);

                // And can read out again in different case
                files = cache["pRoJ"];
                Assert.IsNotNull(files);

                // Null value clears entry
                cache["proj"] = null;
                files = cache["proj"];
                Assert.IsNull(files);

                // ArgNull exception on null/empty index setter
                ExceptionHelper.ExpectArgumentNullExceptionStandard(() => cache[null] = new string[] { "a" }, "projectPath");
                ExceptionHelper.ExpectArgumentNullExceptionStandard(() => cache[string.Empty] = new string[] { "a" }, "projectPath");

                // ArgNull exception on null/empty index getter
                ExceptionHelper.ExpectArgumentNullExceptionStandard(() => files = cache[null], "projectPath");
                ExceptionHelper.ExpectArgumentNullExceptionStandard(() => files = cache[string.Empty], "projectPath");
            }
        }
コード例 #6
0
        public void LinkedServerProjectCache_Indexer()
        {
            ConsoleLogger logger = new ConsoleLogger();
            using (ProjectFileReader projectFileReader = new ProjectFileReader(logger))
            {
                string projectFile = this.CreateMockProjectFile();
                string historyFile = this.CreateMockHistoryFile();
                LinkedServerProjectCache cache = new LinkedServerProjectCache(projectFile, historyFile, logger, projectFileReader);

                try
                {
                    // First access allocates empty instance
                    Assert.IsNotNull(cache.LinkedServerProjectsByProject, "Expected non null dictionary after ctor");
                    Assert.AreEqual(0, cache.LinkedServerProjectsByProject.Count, "Expected empty cache");

                    // Null indexer parameter throws on sets
                    ExceptionHelper.ExpectArgumentNullExceptionStandard((() => cache[null] = "x"), "projectPath");
                    ExceptionHelper.ExpectArgumentNullExceptionStandard((() => cache[string.Empty] = "x"), "projectPath");

                    // Null indexer parameter throws on gets
                    string unused;
                    ExceptionHelper.ExpectArgumentNullExceptionStandard((() => unused = cache[null]), "projectPath");
                    ExceptionHelper.ExpectArgumentNullExceptionStandard((() => unused = cache[string.Empty]), "projectPath");

                    // Indexer setter can be called with valid values
                    cache["proj1"] = "proj1.Web";
                    cache["proj2"] = "proj2.Web";

                    // Nulls are permitted
                    cache["proj3"] = null;

                    Assert.AreEqual(3, cache.LinkedServerProjectsByProject.Count, "Expected this many entries in cache");

                    Assert.AreEqual("proj1.Web", cache["proj1"]);
                    Assert.AreEqual("proj2.Web", cache["proj2"]);
                    Assert.IsNull(cache["proj3"], "Null should have been allowed in cache");

                    // Cache is case insensitive.  Should overwrite entry differing only in case
                    cache["PrOj1"] = "PrOj1.wEb";
                    Assert.AreEqual(3, cache.LinkedServerProjectsByProject.Count, "Key differing only in case should have overwritten existing one");
                    Assert.AreEqual("PrOj1.wEb", cache["PrOj1"]);
                }
                finally
                {
                    File.Delete(projectFile);
                    File.Delete(historyFile);
                }
            }
        }
コード例 #7
0
        public TargetFrameworkResolutionTests()
        {
            var analyzerManagerMock = new Mock <IAnalyzerManager>();
            var projectAnalyzerMock = new Mock <IProjectAnalyzer>();
            var analyzerResultsMock = new Mock <IAnalyzerResults>();

            analyzerManagerMock
            .Setup(m => m.GetProject(It.IsAny <string>()))
            .Returns(projectAnalyzerMock.Object);

            projectAnalyzerMock
            .Setup(m => m.Build())
            .Returns(analyzerResultsMock.Object);

            analyzerResultsMock
            .Setup(m => m.GetEnumerator())
            .Returns(() => _analyzerResults.GetEnumerator());

            _projectFileReader = new ProjectFileReader(manager: analyzerManagerMock.Object);
        }
コード例 #8
0
        public void ProjectFileReader_Nonexistent_Project_File_Warns()
        {
            ConsoleLogger logger = new ConsoleLogger();
            string badProjectPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".csproj");
            using (ProjectFileReader projectFileReader = new ProjectFileReader(logger))
            {
                try
                {
                    projectFileReader.LoadProject(badProjectPath);

                    string warningMessage = string.Format(CultureInfo.CurrentCulture, Resource.Project_Does_Not_Exist, badProjectPath);

                    TestHelper.AssertContainsWarnings(logger, new string[] { warningMessage });
                }
                finally
                {
                    File.Delete(badProjectPath);
                }
            }
        }
コード例 #9
0
        public void ProjectFileReader_Nonexistent_Project_File_Warns()
        {
            ConsoleLogger logger         = new ConsoleLogger();
            string        badProjectPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".csproj");

            using (ProjectFileReader projectFileReader = new ProjectFileReader(logger))
            {
                try
                {
                    projectFileReader.LoadProject(badProjectPath);

                    string warningMessage = string.Format(CultureInfo.CurrentCulture, Resource.Project_Does_Not_Exist, badProjectPath);

                    TestHelper.AssertContainsWarnings(logger, new string[] { warningMessage });
                }
                finally
                {
                    File.Delete(badProjectPath);
                }
            }
        }
コード例 #10
0
        public void LinkedServerProjectCache_RiaLinks()
        {
            ConsoleLogger logger = new ConsoleLogger();

            using (ProjectFileReader projectFileReader = new ProjectFileReader(logger))
            {
                string projectFile = this.CreateMockProjectFile();
                string historyFile = this.CreateMockHistoryFile();

                try
                {
                    LinkedServerProjectCache cache = new LinkedServerProjectCache(projectFile, historyFile, logger, projectFileReader);

                    cache["p1"] = "w1";
                    cache["p2"] = null;
                    cache["p3"] = "w3";
                    cache["p4"] = string.Empty;

                    Assert.AreEqual(4, cache.LinkedServerProjectsByProject.Count, "Should have had this many items in cache");

                    List <string> projectRefs = cache.ProjectReferences.ToList();
                    Assert.AreEqual(4, projectRefs.Count, "Expected to have this many project references in cache");

                    Assert.IsTrue(projectRefs.Contains("p1"), "expected p1 to be in list of project refs");
                    Assert.IsTrue(projectRefs.Contains("p2"), "expected p2 to be in list of project refs");
                    Assert.IsTrue(projectRefs.Contains("p3"), "expected p3 to be in list of project refs");
                    Assert.IsTrue(projectRefs.Contains("p4"), "expected p4 to be in list of project refs");

                    List <string> riaLinks = cache.LinkedServerProjects.ToList();
                    Assert.AreEqual(2, riaLinks.Count, "Expected this many project references to have RIA Links");
                    Assert.IsTrue(riaLinks.Contains("w1"), "expected p1 to be in list of RIA links");
                    Assert.IsTrue(riaLinks.Contains("w3"), "expected p3 to be in list of RIA links");
                }
                finally
                {
                    File.Delete(projectFile);
                    File.Delete(historyFile);
                }
            }
        }
コード例 #11
0
        public void ProjectSourceFileCache_Nonexistent_Project_File_Warns()
        {
            ConsoleLogger logger         = new ConsoleLogger();
            string        badProjectPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".csproj");

            using (ProjectFileReader projectFileReader = new ProjectFileReader(logger))
            {
                try
                {
                    ProjectSourceFileCache cache    = new ProjectSourceFileCache(badProjectPath, "breadCrumb", logger, projectFileReader);
                    IEnumerable <string>   projects = cache.GetAllKnownProjects();

                    string warningMessage = string.Format(CultureInfo.CurrentCulture, Resource.Project_Does_Not_Exist, badProjectPath);

                    TestHelper.AssertContainsWarnings(logger, new string[] { warningMessage });
                }
                finally
                {
                    File.Delete(badProjectPath);
                }
            }
        }
コード例 #12
0
        public void ProjectFileReader_Bad_Project_File_Warns()
        {
            ConsoleLogger logger = new ConsoleLogger();

            using (ProjectFileReader projectFileReader = new ProjectFileReader(logger))
            {
                string badProjectPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".csproj");
                File.WriteAllText(badProjectPath, "neener neener");

                try
                {
                    projectFileReader.LoadProject(badProjectPath);

                    // Simulate the exception so we get the exact text
                    string warningMessage = TestHelper.GetFailedToOpenProjectMessage(badProjectPath);
                    TestHelper.AssertContainsWarnings(logger, new string[] { warningMessage });
                }
                finally
                {
                    File.Delete(badProjectPath);
                }
            }
        }
コード例 #13
0
        public void CommandViewModelTo(GetProjectName cmd)
        {
            ProjectFileReader Reader = new ProjectFileReader(cmd.LoadedProjectFileAbsolutePath);

            cmd.FetchedProjectName = Reader.LoadProjectName();
        }
コード例 #14
0
        public void LinkedServerProjectCache_Load_Real_Project()
        {
            ConsoleLogger logger = new ConsoleLogger();
            using (ProjectFileReader projectFileReader = new ProjectFileReader(logger))
            {

                // We will create valid MSBuild projects with this shape:
                //  - projectFile: contains 3 project references
                //  - 2 of the 3 projects referenced point to unique RIA Link server project
                //  - 1 of the 3 projects references points to the same RIA Link project as another
                //     (this tests the ability of our model to handle multiple clients pointing to the same server)
                string serverProject1 = this.CreateMockProjectFile();
                string serverProject2 = this.CreateMockProjectFile();

                string refProject1Contents = string.Format(@"
<Project ToolsVersion=""4.0"" DefaultTargets=""Build"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
  <PropertyGroup>
    <LinkedOpenRiaServerProject>{0}</LinkedOpenRiaServerProject>
  </PropertyGroup>
</Project>", serverProject1);

                string refProject2Contents = string.Format(@"
<Project ToolsVersion=""4.0"" DefaultTargets=""Build"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
  <PropertyGroup>
    <LinkedOpenRiaServerProject>{0}</LinkedOpenRiaServerProject>
  </PropertyGroup>
</Project>", serverProject2);

                string refProject1 = this.CreateTempFile("csproj", refProject1Contents);
                string refProject2 = this.CreateTempFile("csproj", refProject2Contents);
                string refProject3 = this.CreateTempFile("csproj", refProject2Contents);

                string projectContents = string.Format(@"
<Project ToolsVersion=""4.0"" DefaultTargets=""Build"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
  <ItemGroup>
    <ProjectReference Include=""{0}""></ProjectReference>
    <ProjectReference Include=""{1}""></ProjectReference>
    <ProjectReference Include=""{2}""></ProjectReference>
  </ItemGroup>
</Project>", refProject1, refProject2, refProject3);

                string projectFile = this.CreateTempFile("csproj", projectContents);
                string historyFile = this.CreateTempFile("txt", null);  // <-- null prevents us from creating file on disk
                try
                {
                    LinkedServerProjectCache cache = new LinkedServerProjectCache(projectFile, historyFile, logger, projectFileReader);

                    // Validate we see our 3 project references
                    List<string> projectRefs = cache.ProjectReferences.ToList();
                    Assert.AreEqual(3, projectRefs.Count, "Expected this many project references");
                    Assert.IsTrue(projectRefs.Contains(refProject1), "Expected ref project 1 in project references.");
                    Assert.IsTrue(projectRefs.Contains(refProject2), "Expected ref project 2 in project references.");
                    Assert.IsTrue(projectRefs.Contains(refProject3), "Expected ref project 3 in project references.");

                    // Validate that we extracted the RIA Links for those project references
                    List<string> riaLinks = cache.LinkedServerProjects.ToList();
                    Assert.AreEqual(2, riaLinks.Count, "Expected to find 2 RIA links");
                    Assert.IsTrue(riaLinks.Contains(serverProject1), "Expected server project 1 RIA link");
                    Assert.IsTrue(riaLinks.Contains(serverProject2), "Expected server project 2 RIA link");

                    // Validate that we can ask for the source of each RIA Link target
                    List<string> sources = cache.GetLinkedServerProjectSources(serverProject1).ToList();
                    Assert.AreEqual(1, sources.Count, "Expected 1 source to for RIA link to server project 1");
                    Assert.IsTrue(sources.Contains(refProject1), "Expected refProject 1 to be shown as RIA Link source 1");

                    sources = cache.GetLinkedServerProjectSources(serverProject2).ToList();
                    Assert.AreEqual(2, sources.Count, "Expected 2 sources to for RIA link to server project 2");
                    Assert.IsTrue(sources.Contains(refProject2), "Expected refProject 2 to be shown as RIA Link source 2");
                    Assert.IsTrue(sources.Contains(refProject3), "Expected refProject 2 to be shown as RIA Link source 2");
                }
                finally
                {
                    File.Delete(projectFile);
                    File.Delete(historyFile);
                    File.Delete(refProject1);
                    File.Delete(refProject2);
                    File.Delete(refProject3);
                    File.Delete(serverProject1);
                    File.Delete(serverProject2);

                }
            }
        }
コード例 #15
0
        public void LinkedServerProjectCache_LoadAndSaveFile()
        {
            ConsoleLogger logger = new ConsoleLogger();
            using (ProjectFileReader projectFileReader = new ProjectFileReader(logger))
            {

                string historyFile = this.CreateMockHistoryFile();
                string projectFile = this.CreateMockProjectFile();
                string p1 = this.CreateMockProjectFile();
                string p2 = this.CreateMockProjectFile();
                string p3 = this.CreateMockProjectFile();
                string p4 = this.CreateMockProjectFile();

                string w1 = this.CreateMockProjectFile();
                string w3 = this.CreateMockProjectFile();

                LinkedServerProjectCache cache = new LinkedServerProjectCache(projectFile, historyFile, logger, projectFileReader);

                cache[p1] = w1;
                cache[p2] = null;
                cache[p3] = w3;
                cache[p4] = string.Empty;

                Assert.IsFalse(cache.IsFileCacheCurrent, "expected file cache not to be current after set some properties");

                try
                {
                    // Save to the cache and verify side effects of that
                    bool success = cache.SaveCacheToFile();
                    Assert.IsTrue(success, "Expected successful save of cache to history file");
                    Assert.IsTrue(File.Exists(historyFile), "Expected history file " + historyFile + " to have been written");

                    Assert.IsTrue(cache.IsFileCacheCurrent, "Expected cache to be considered current");

                    // zap our cache and read back in from file
                    cache = new LinkedServerProjectCache(projectFile, historyFile, logger, projectFileReader);

                    // The following methods and properties will lazy load the cache
                    Assert.AreEqual(4, cache.LinkedServerProjectsByProject.Count, "Should have had this many items in cache");

                    List<string> projectRefs = cache.ProjectReferences.ToList();
                    Assert.AreEqual(4, projectRefs.Count, "Expected to have this many project references in cache");

                    Assert.IsTrue(projectRefs.Contains(p1), "expected p1 to be in list of project refs");
                    Assert.IsTrue(projectRefs.Contains(p2), "expected p2 to be in list of project refs");
                    Assert.IsTrue(projectRefs.Contains(p3), "expected p3 to be in list of project refs");
                    Assert.IsTrue(projectRefs.Contains(p4), "expected p4 to be in list of project refs");

                    List<string> riaLinks = cache.LinkedServerProjects.ToList();
                    Assert.AreEqual(2, riaLinks.Count, "Expected this many project references to have RIA Links");
                    Assert.IsTrue(riaLinks.Contains(w1), "expected w1 to be in list of RIA links");
                    Assert.IsTrue(riaLinks.Contains(w3), "expected w3 to be in list of RIA links");
                }
                finally
                {
                    File.Delete(historyFile);
                    File.Delete(projectFile);
                    File.Delete(p1);
                    File.Delete(p2);
                    File.Delete(p3);
                    File.Delete(p4);
                    File.Delete(w1);
                    File.Delete(w3);
                }
            }
        }
コード例 #16
0
        public void LinkedServerProjectCache_RiaLinks()
        {
            ConsoleLogger logger = new ConsoleLogger();
            using (ProjectFileReader projectFileReader = new ProjectFileReader(logger))
            {
                string projectFile = this.CreateMockProjectFile();
                string historyFile = this.CreateMockHistoryFile();

                try
                {
                    LinkedServerProjectCache cache = new LinkedServerProjectCache(projectFile, historyFile, logger, projectFileReader);

                    cache["p1"] = "w1";
                    cache["p2"] = null;
                    cache["p3"] = "w3";
                    cache["p4"] = string.Empty;

                    Assert.AreEqual(4, cache.LinkedServerProjectsByProject.Count, "Should have had this many items in cache");

                    List<string> projectRefs = cache.ProjectReferences.ToList();
                    Assert.AreEqual(4, projectRefs.Count, "Expected to have this many project references in cache");

                    Assert.IsTrue(projectRefs.Contains("p1"), "expected p1 to be in list of project refs");
                    Assert.IsTrue(projectRefs.Contains("p2"), "expected p2 to be in list of project refs");
                    Assert.IsTrue(projectRefs.Contains("p3"), "expected p3 to be in list of project refs");
                    Assert.IsTrue(projectRefs.Contains("p4"), "expected p4 to be in list of project refs");

                    List<string> riaLinks = cache.LinkedServerProjects.ToList();
                    Assert.AreEqual(2, riaLinks.Count, "Expected this many project references to have RIA Links");
                    Assert.IsTrue(riaLinks.Contains("w1"), "expected p1 to be in list of RIA links");
                    Assert.IsTrue(riaLinks.Contains("w3"), "expected p3 to be in list of RIA links");
                }
                finally
                {
                    File.Delete(projectFile);
                    File.Delete(historyFile);
                }
            }
        }
コード例 #17
0
        public void ProjectSourceFileCache_Loads_Real_Project()
        {
            string projectPath = null;
            string outputPath  = null;

            TestHelper.GetProjectPaths("SSFC", out projectPath, out outputPath);
            string        serverProjectPath = CodeGenHelper.ServerClassLibProjectPath(projectPath);
            string        breadCrumbFile    = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".txt");
            ConsoleLogger logger            = new ConsoleLogger();

            using (ProjectFileReader projectFileReader = new ProjectFileReader(logger))
            {
                try
                {
                    // Instantiate the cache.
                    ProjectSourceFileCache cache = new ProjectSourceFileCache(serverProjectPath, breadCrumbFile, logger, projectFileReader);

                    // Initially, it will not have loaded anything
                    Assert.AreEqual(0, cache.SourceFilesByProject.Count);

                    // -------------------------------------------------------------
                    // Validate cache is loaded correctly from .csproj files
                    // -------------------------------------------------------------
                    this.ValidateProjectSourceFileCache(cache, projectPath);

                    // Ask to write out the breadcrumb file
                    Assert.IsFalse(File.Exists(breadCrumbFile));
                    bool success = cache.SaveCacheToFile();
                    Assert.IsTrue(success);
                    Assert.IsTrue(File.Exists(breadCrumbFile));

                    // Clear the cache and force it to read from breadcrumb
                    cache.SourceFilesByProject.Clear();

                    success = cache.LoadCacheFromFile();
                    Assert.IsTrue(success, "Failed to load from breadCrumb file");
                    Assert.IsTrue(cache.IsFileCacheCurrent, "Loading from file should have marked cache as current with file.");

                    // -------------------------------------------------------------
                    // Validate cache is loaded correctly from breadcrumb file
                    // -------------------------------------------------------------
                    this.ValidateProjectSourceFileCache(cache, projectPath);

                    // Now mark the breadcrumb file as if it had been written before the ServerClassLib project
                    cache.SourceFilesByProject.Clear();

                    DateTime serverLastWriteTime       = File.GetLastWriteTime(serverProjectPath);
                    DateTime beforeServerLastWriteTime = new DateTime(serverLastWriteTime.Ticks - 1000);
                    File.SetLastWriteTime(breadCrumbFile, beforeServerLastWriteTime);

                    // -------------------------------------------------------------
                    // Validate cache is *not* loaded if timestamp is before project's
                    // -------------------------------------------------------------
                    success = cache.LoadCacheFromFile();
                    Assert.IsFalse(success, "Expected breadCrumbFile time stamp to be caught and reject load");
                    Assert.IsFalse(cache.IsFileCacheCurrent, "Failed load from file should have marked cache as *not* current with file.");

                    // Cache should still be empty
                    Assert.AreEqual(0, cache.SourceFilesByProject.Count);

                    // -------------------------------------------------------------
                    // Validate cache loaded in presence of out-of-date breadcrumb
                    // file loads correctly
                    // -------------------------------------------------------------
                    this.ValidateProjectSourceFileCache(cache, projectPath);

                    Assert.IsFalse(cache.IsFileCacheCurrent, "Loading from project should have marked cache as *not* current with file.");
                }
                finally
                {
                    if (File.Exists(breadCrumbFile))
                    {
                        File.Delete(breadCrumbFile);
                    }
                }
            }
        }
コード例 #18
0
        public void ProjectSourceFileCache_Nonexistent_Project_File_SourceFiles_Warns()
        {
            ConsoleLogger logger = new ConsoleLogger();
            using (ProjectFileReader projectFileReader = new ProjectFileReader(logger))
            {
                string badProjectPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".csproj");

                try
                {
                    ProjectSourceFileCache cache = new ProjectSourceFileCache("proj", "breadCrumb", logger, projectFileReader);
                    IEnumerable<string> sourceFiles = projectFileReader.LoadSourceFilesFromProject(badProjectPath);

                    string warningMessage = string.Format(CultureInfo.CurrentCulture, Resource.Project_Does_Not_Exist, badProjectPath);

                    TestHelper.AssertContainsWarnings(logger, new string[] { warningMessage });

                }
                finally
                {
                    File.Delete(badProjectPath);
                }
            }
        }
コード例 #19
0
        /// <summary>
        /// Creates a new instance
        /// </summary>
        /// <param name="rootProjectPath">Full file path to client project to use as root.</param>
        /// <param name="historyFilePath">Full file path to file to read and write in-memory cache.</param>
        /// <param name="logger">Instance of an <see cref="ILogger"/> to receive messages.</param>
        /// <param name="projectFileReader">Instance to use to read the project files.</param>
        internal LinkedServerProjectCache(string rootProjectPath, string historyFilePath, ILogger logger, ProjectFileReader projectFileReader)
        {
            if (string.IsNullOrEmpty(rootProjectPath))
            {
                throw new ArgumentNullException("rootProjectPath");
            }

            if (string.IsNullOrEmpty(historyFilePath))
            {
                throw new ArgumentNullException("historyFilePath");
            }

            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            if (projectFileReader == null)
            {
                throw new ArgumentNullException("projectFileReader");
            }

            _rootProjectPath   = rootProjectPath;
            _historyFilePath   = historyFilePath;
            _logger            = logger;
            _projectFileReader = projectFileReader;
        }
コード例 #20
0
#pragma warning restore CS0164

        private void DebugButton_Click(object sender, EventArgs e)
        {
            bool   outputSessionData = checkBox1.Checked;
            bool   parseCodeData     = checkBox2.Checked;
            bool   outputTextCode    = checkBox3.Checked;
            string fileName          = textBox2.Text;

            textBox1.Text = "正在处理...";

            new Task(() =>
            {
                try
                {
                    CodeSectionInfo codeSectionInfo         = null;
                    ResourceSectionInfo resourceSectionInfo = null;
                    LosableSectionInfo losableSectionInfo   = null;
                    Encoding encoding = Encoding.GetEncoding("gbk");
                    var output        = new StringBuilder();
                    using (var projectFileReader = new ProjectFileReader(File.OpenRead(fileName), InputPassword))
                    {
                        while (!projectFileReader.IsFinish)
                        {
                            var section = projectFileReader.ReadSection();
                            if (outputSessionData)
                            {
                                output.AppendLine("---------------" + section.Name + "---------------");
                                output.AppendLine("CanSkip: " + section.CanSkip.ToString());
                                output.AppendLine("Key: 0x" + section.Key.ToString("X8"));
                                output.Append("Data: ");
                            }
                            switch (section.Key)
                            {
                            case ESystemInfo.SectionKey:
                                {
                                    var systemInfo = ESystemInfo.Parse(section.Data);
                                    encoding       = systemInfo.Encoding;
                                    if (outputSessionData)
                                    {
                                        output.AppendLine(systemInfo.ToString());
                                    }
                                }
                                break;

                            case ProjectConfigInfo.SectionKey:
                                {
                                    var projectConfig = ProjectConfigInfo.Parse(section.Data, encoding);
                                    if (outputSessionData)
                                    {
                                        output.AppendLine(projectConfig.ToString());
                                    }
                                }
                                break;

                            case CodeSectionInfo.SectionKey:
                                codeSectionInfo = CodeSectionInfo.Parse(section.Data, encoding, projectFileReader.CryptEc);
                                if (outputSessionData)
                                {
                                    output.AppendLine(codeSectionInfo.ToString());
                                }
                                break;

                            case EPackageInfo.SectionKey:
                                {
                                    var packageInfo = EPackageInfo.Parse(section.Data, encoding);
                                    if (outputSessionData)
                                    {
                                        output.AppendLine(packageInfo.ToString());
                                    }
                                }
                                break;

                            case ResourceSectionInfo.SectionKey:
                                resourceSectionInfo = ResourceSectionInfo.Parse(section.Data, encoding);
                                if (outputSessionData)
                                {
                                    output.AppendLine(resourceSectionInfo.ToString());
                                }
                                break;

                            case InitEcSectionInfo.SectionKey:
                                {
                                    var initEcSectionInfo = InitEcSectionInfo.Parse(section.Data, encoding);
                                    if (outputSessionData)
                                    {
                                        output.AppendLine(initEcSectionInfo.ToString());
                                    }
                                }
                                break;

                            case LosableSectionInfo.SectionKey:
                                {
                                    losableSectionInfo = LosableSectionInfo.Parse(section.Data, encoding);
                                    if (outputSessionData)
                                    {
                                        output.AppendLine(losableSectionInfo.ToString());
                                    }
                                }
                                break;

                            case FolderSectionInfo.SectionKey:
                                {
                                    var folderSectionInfo = FolderSectionInfo.Parse(section.Data, encoding);
                                    if (outputSessionData)
                                    {
                                        output.AppendLine(folderSectionInfo.ToString());
                                    }
                                }
                                break;

                            default:
                                if (outputSessionData)
                                {
                                    output.AppendLine("{");
                                    output.Append("  \"Unknown\": \"");
                                    output.Append(section.Data.ToHexString());
                                    output.AppendLine("\"");
                                    output.AppendLine("}");
                                }
                                break;
                            }
                        }
                        if (parseCodeData)
                        {
                            output.AppendLine("<<<<<<<<<<<<<<<ParseTest>>>>>>>>>>>>>>>");
                            foreach (var method in codeSectionInfo.Methods)
                            {
                                output.AppendLine($"###Method: {(string.IsNullOrEmpty(method.Name) ? "Unknown" : method.Name)}{$"Id: {method.Id})###"}");
                                try
                                {
#pragma warning disable CS0612 // 类型或成员已过时
                                    var block = CodeDataParser.ParseStatementBlock(method.CodeData.ExpressionData, encoding, out var lineOffest, out var blockOffest);
#pragma warning restore CS0612 // 类型或成员已过时
                                    var GenCodeData = block.ToCodeData(encoding);
                                    output.Append("Raw: ");
                                    output.AppendLine(method.CodeData.ToString());
                                    output.Append("FullRewrite: ");
                                    output.AppendLine(GenCodeData.ToString());
                                    output.Append("OldOffestRepairer: ");
                                    output.AppendLine("{");
                                    output.AppendLine("  \"LineOffest\": \"" + lineOffest.ToHexString() + "\"");
                                    output.AppendLine("  \"BlockOffest\": \"" + blockOffest.ToHexString() + "\"");
                                    output.AppendLine("}");
                                }
                                catch (Exception exception)
                                {
                                    output.AppendLine("出现错误:");
                                    output.AppendLine(exception.ToString());
                                    output.AppendLine();
                                }
                            }
                        }
                        if (outputTextCode)
                        {
                            output.AppendLine("<<<<<<<<<<<<<<<TextCode>>>>>>>>>>>>>>>");
                            var nameMap = new IdToNameMap(codeSectionInfo, resourceSectionInfo, losableSectionInfo);
                            output.AppendLine(".版本 2");
                            output.AppendLine();
                            output.AppendLine(codeSectionInfo.ToTextCode(nameMap));
                            output.AppendLine(resourceSectionInfo.ToTextCode(nameMap));
                        }
                    }
                    Invoke(new Action(() =>
                    {
                        textBox1.Text = output.ToString();
                    }));
                }
                catch (Exception exception)
                {
                    Invoke(new Action(() =>
                    {
                        textBox1.Text = $"出现错误:\r\n{exception}\r\n请加群后将文件发送给作者以便修复此问题";
                    }));
                }
            })
            .Start();
        }
コード例 #21
0
        /// <summary>
        /// Sole constructor
        /// </summary>
        /// <param name="rootProjectPath">Full path to the root project file.</param>
        /// <param name="historyFilePath">Full path to the file where we are allowed to write results between builds.</param>
        /// <param name="logger">The <see cref="ILogger"/> to use for warnings and errors.</param>
        /// <param name="projectFileReader">Instance to use to read the project files.</param>
        internal ProjectSourceFileCache(string rootProjectPath, string historyFilePath, ILogger logger, ProjectFileReader projectFileReader)
        {
            if (string.IsNullOrEmpty(rootProjectPath))
            {
                throw new ArgumentNullException("rootProjectPath");
            }

            if (string.IsNullOrEmpty(historyFilePath))
            {
                throw new ArgumentNullException("historyFilePath");
            }

            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            if (projectFileReader == null)
            {
                throw new ArgumentNullException("projectFileReader");
            }

            this._rootProjectPath   = rootProjectPath;
            this._historyFilePath   = historyFilePath;
            this._projectFileReader = projectFileReader;
            this._logger            = logger;
        }
コード例 #22
0
        /// <summary>
        /// Loads the internal state from the breadcrumb file passed to the ctor.
        /// </summary>
        /// <remarks>
        /// If the root project has been modified since the breadcrumb file
        /// was written, the entire cache is considered invalid and <c>false</c> is returned.
        /// If any cached project has been touched since the cache was last written, just
        /// is portion of the cache will be reloaded from the project file.
        /// </remarks>
        /// <returns>A <c>true</c> means the cache was loaded from the breadcrumb file successfully.
        /// If we detect the cache is out of date or does not exist, a <c>false</c> is returned.
        /// </returns>
        internal bool LoadCacheFromFile()
        {
            this.IsFileCacheCurrent = false;

            if (!File.Exists(this._historyFilePath))
            {
                return(false);
            }

            // If the root project itself has been touched since the
            // time we wrote the file, we can't trust anything in our cache
            DateTime projectWriteTime    = File.GetLastWriteTime(this._rootProjectPath);
            DateTime breadCrumbWriteTime = File.GetLastWriteTime(this._historyFilePath);

            if (projectWriteTime.CompareTo(breadCrumbWriteTime) > 0)
            {
                return(false);
            }

            // Read the breadcrumb file.
            // Format is:
            //  One line per project: path, lastWriteTime, list of source files separated by commas
            string fileContents = File.ReadAllText(this._historyFilePath);

            string[] projectEntries = fileContents.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string projectEntry in projectEntries)
            {
                string[] projectItems = projectEntry.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                // Fewer than 2 is formatting problem -- maybe the file is corrupt.  Just discard cache and rebuild.
                if (projectItems.Length < 2)
                {
                    // Always clear out any partial results when returning false
                    this.SourceFilesByProject.Clear();
                    return(false);
                }
                string projectPath = projectItems[0];

                // If that project no longer exists, remove it from the cache but keep running
                if (!File.Exists(projectPath))
                {
                    continue;
                }

                List <string> files = new List <string>();

                // Projects with no source files have only the first 2 items (name and timestamp).
                // Those will be added to our cache with an empty list to show that we know they
                // have no source files (otherwise, we would need to open them again to know).
                // Any project with some number of source files falls into the body of this 'if'
                if (projectItems.Length >= 3)
                {
                    // Check whether the project file was touched since the last time
                    // we analyzed it.  Failure to parse last write time or discovery
                    // the project has been touched more recently causes us to reload
                    // just that project.  Incidentally, the use of Ticks here is more
                    // reliable than DateTime.ToString() which does not round-trip accurately.
                    projectWriteTime = File.GetLastWriteTime(projectPath);
                    long breadCrumbWriteTimeTicks = 0;
                    if (!long.TryParse(projectItems[1], out breadCrumbWriteTimeTicks) || projectWriteTime.Ticks > breadCrumbWriteTimeTicks)
                    {
                        // Go load from the project file and ignore what we had cached
                        files.AddRange(this._projectFileReader.LoadSourceFilesFromProject(projectPath));
                    }
                    else
                    {
                        // The last write time shows the project has not changed since
                        // we cached the results, so extract them from the text
                        for (int i = 2; i < projectItems.Length; ++i)
                        {
                            string file = projectItems[i];
                            if (string.IsNullOrEmpty(file))
                            {
                                continue;
                            }

                            // We write relative paths, so convert back to full
                            string fullFilePath = ProjectFileReader.ConvertToFullPath(file, projectPath);

                            // If the file has ceased to exist, but the project says it
                            // does, we do not add it to our internal lists
                            if (File.Exists(fullFilePath))
                            {
                                files.Add(fullFilePath);
                            }
                        }
                    }
                }
                this[projectPath] = files;
            }
            this.IsFileCacheCurrent = true;
            return(true);
        }
コード例 #23
0
        public void ProjectSourceFileCache_Loads_Real_Project()
        {
            string projectPath = null;
            string outputPath = null;
            TestHelper.GetProjectPaths("SSFC", out projectPath, out outputPath);
            string serverProjectPath = CodeGenHelper.ServerClassLibProjectPath(projectPath);
            string breadCrumbFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".txt");
            ConsoleLogger logger = new ConsoleLogger();
            using (ProjectFileReader projectFileReader = new ProjectFileReader(logger))
            {

                try
                {
                    // Instantiate the cache.
                    ProjectSourceFileCache cache = new ProjectSourceFileCache(serverProjectPath, breadCrumbFile, logger, projectFileReader);

                    // Initially, it will not have loaded anything
                    Assert.AreEqual(0, cache.SourceFilesByProject.Count);

                    // -------------------------------------------------------------
                    // Validate cache is loaded correctly from .csproj files
                    // -------------------------------------------------------------
                    this.ValidateProjectSourceFileCache(cache, projectPath);

                    // Ask to write out the breadcrumb file
                    Assert.IsFalse(File.Exists(breadCrumbFile));
                    bool success = cache.SaveCacheToFile();
                    Assert.IsTrue(success);
                    Assert.IsTrue(File.Exists(breadCrumbFile));

                    // Clear the cache and force it to read from breadcrumb
                    cache.SourceFilesByProject.Clear();

                    success = cache.LoadCacheFromFile();
                    Assert.IsTrue(success, "Failed to load from breadCrumb file");
                    Assert.IsTrue(cache.IsFileCacheCurrent, "Loading from file should have marked cache as current with file.");

                    // -------------------------------------------------------------
                    // Validate cache is loaded correctly from breadcrumb file
                    // -------------------------------------------------------------
                    this.ValidateProjectSourceFileCache(cache, projectPath);

                    // Now mark the breadcrumb file as if it had been written before the ServerClassLib project
                    cache.SourceFilesByProject.Clear();

                    DateTime serverLastWriteTime = File.GetLastWriteTime(serverProjectPath);
                    DateTime beforeServerLastWriteTime = new DateTime(serverLastWriteTime.Ticks - 1000);
                    File.SetLastWriteTime(breadCrumbFile, beforeServerLastWriteTime);

                    // -------------------------------------------------------------
                    // Validate cache is *not* loaded if timestamp is before project's
                    // -------------------------------------------------------------
                    success = cache.LoadCacheFromFile();
                    Assert.IsFalse(success, "Expected breadCrumbFile time stamp to be caught and reject load");
                    Assert.IsFalse(cache.IsFileCacheCurrent, "Failed load from file should have marked cache as *not* current with file.");

                    // Cache should still be empty
                    Assert.AreEqual(0, cache.SourceFilesByProject.Count);

                    // -------------------------------------------------------------
                    // Validate cache loaded in presence of out-of-date breadcrumb
                    // file loads correctly
                    // -------------------------------------------------------------
                    this.ValidateProjectSourceFileCache(cache, projectPath);

                    Assert.IsFalse(cache.IsFileCacheCurrent, "Loading from project should have marked cache as *not* current with file.");
                }
                finally
                {
                    if (File.Exists(breadCrumbFile))
                        File.Delete(breadCrumbFile);
                }
            }
        }
コード例 #24
0
        public void ProjectSourceFileCache_Failed_BreadCrumb_Save_Warns()
        {
            ConsoleLogger logger = new ConsoleLogger();
            using (ProjectFileReader projectFileReader = new ProjectFileReader(logger))
            {
                string projectPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".csproj");
                string breadCrumbPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".txt");
                string csFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".cs");

                // Need file on disk only for timestamp
                File.WriteAllText(projectPath, "neener neener");
                File.WriteAllText(breadCrumbPath, "bread crumbs");
                File.WriteAllText(csFile, "//");

                try
                {
                    ProjectSourceFileCache cache = new ProjectSourceFileCache(projectPath, breadCrumbPath, logger, projectFileReader);
                    cache.SourceFilesByProject[projectPath] = new string[] { csFile };

                    // Setup for failure
                    File.SetAttributes(breadCrumbPath, FileAttributes.ReadOnly);

                    // Ask to write to readonly file -- should fail
                    cache.SaveCacheToFile();

                    // Simulate the exception so we get the exact text
                    string warningMessage = null;
                    try
                    {

                        // this should fail
                        File.WriteAllText(breadCrumbPath, "stuff");
                    }
                    catch (UnauthorizedAccessException uae)
                    {
                        warningMessage = string.Format(CultureInfo.CurrentCulture, Resource.Failed_To_Write_File, breadCrumbPath, uae.Message);
                    }

                    TestHelper.AssertContainsWarnings(logger, new string[] { warningMessage });

                }
                finally
                {
                    File.Delete(projectPath);
                    File.SetAttributes(breadCrumbPath, File.GetAttributes(breadCrumbPath) & ~FileAttributes.ReadOnly);
                    File.Delete(breadCrumbPath);
                    File.Delete(csFile);
                }
            }
        }
コード例 #25
0
        public void LinkedServerProjectCache_LoadAndSaveFile()
        {
            ConsoleLogger logger = new ConsoleLogger();

            using (ProjectFileReader projectFileReader = new ProjectFileReader(logger))
            {
                string historyFile = this.CreateMockHistoryFile();
                string projectFile = this.CreateMockProjectFile();
                string p1          = this.CreateMockProjectFile();
                string p2          = this.CreateMockProjectFile();
                string p3          = this.CreateMockProjectFile();
                string p4          = this.CreateMockProjectFile();

                string w1 = this.CreateMockProjectFile();
                string w3 = this.CreateMockProjectFile();

                LinkedServerProjectCache cache = new LinkedServerProjectCache(projectFile, historyFile, logger, projectFileReader);

                cache[p1] = w1;
                cache[p2] = null;
                cache[p3] = w3;
                cache[p4] = string.Empty;

                Assert.IsFalse(cache.IsFileCacheCurrent, "expected file cache not to be current after set some properties");

                try
                {
                    // Save to the cache and verify side effects of that
                    bool success = cache.SaveCacheToFile();
                    Assert.IsTrue(success, "Expected successful save of cache to history file");
                    Assert.IsTrue(File.Exists(historyFile), "Expected history file " + historyFile + " to have been written");

                    Assert.IsTrue(cache.IsFileCacheCurrent, "Expected cache to be considered current");

                    // zap our cache and read back in from file
                    cache = new LinkedServerProjectCache(projectFile, historyFile, logger, projectFileReader);

                    // The following methods and properties will lazy load the cache
                    Assert.AreEqual(4, cache.LinkedServerProjectsByProject.Count, "Should have had this many items in cache");

                    List <string> projectRefs = cache.ProjectReferences.ToList();
                    Assert.AreEqual(4, projectRefs.Count, "Expected to have this many project references in cache");

                    Assert.IsTrue(projectRefs.Contains(p1), "expected p1 to be in list of project refs");
                    Assert.IsTrue(projectRefs.Contains(p2), "expected p2 to be in list of project refs");
                    Assert.IsTrue(projectRefs.Contains(p3), "expected p3 to be in list of project refs");
                    Assert.IsTrue(projectRefs.Contains(p4), "expected p4 to be in list of project refs");

                    List <string> riaLinks = cache.LinkedServerProjects.ToList();
                    Assert.AreEqual(2, riaLinks.Count, "Expected this many project references to have RIA Links");
                    Assert.IsTrue(riaLinks.Contains(w1), "expected w1 to be in list of RIA links");
                    Assert.IsTrue(riaLinks.Contains(w3), "expected w3 to be in list of RIA links");
                }
                finally
                {
                    File.Delete(historyFile);
                    File.Delete(projectFile);
                    File.Delete(p1);
                    File.Delete(p2);
                    File.Delete(p3);
                    File.Delete(p4);
                    File.Delete(w1);
                    File.Delete(w3);
                }
            }
        }
コード例 #26
0
        public void ProjectSourceFileCache_AllKnownProjects()
        {
            ConsoleLogger logger = new ConsoleLogger();
            using (ProjectFileReader projectFileReader = new ProjectFileReader(logger))
            {
                ProjectSourceFileCache cache = new ProjectSourceFileCache("proj", "breadCrumb", logger, projectFileReader);

                cache["p1"] = new string[] { "a", "b" };
                cache["p2"] = new string[] { "c" };

                IEnumerable<string> projects = cache.GetAllKnownProjects();
                Assert.IsNotNull(projects);
                Assert.AreEqual(2, projects.Count());
                Assert.IsTrue(projects.Contains("p1"));
                Assert.IsTrue(projects.Contains("p2"));
            }
        }
コード例 #27
0
        public void LinkedServerProjectCache_Load_Real_Project()
        {
            ConsoleLogger logger = new ConsoleLogger();

            using (ProjectFileReader projectFileReader = new ProjectFileReader(logger))
            {
                // We will create valid MSBuild projects with this shape:
                //  - projectFile: contains 3 project references
                //  - 2 of the 3 projects referenced point to unique RIA Link server project
                //  - 1 of the 3 projects references points to the same RIA Link project as another
                //     (this tests the ability of our model to handle multiple clients pointing to the same server)
                string serverProject1 = this.CreateMockProjectFile();
                string serverProject2 = this.CreateMockProjectFile();

                string refProject1Contents = string.Format(@"
<Project ToolsVersion=""4.0"" DefaultTargets=""Build"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
  <PropertyGroup>
    <LinkedOpenRiaServerProject>{0}</LinkedOpenRiaServerProject>
  </PropertyGroup>
</Project>", serverProject1);

                string refProject2Contents = string.Format(@"
<Project ToolsVersion=""4.0"" DefaultTargets=""Build"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
  <PropertyGroup>
    <LinkedOpenRiaServerProject>{0}</LinkedOpenRiaServerProject>
  </PropertyGroup>
</Project>", serverProject2);

                string refProject1 = this.CreateTempFile("csproj", refProject1Contents);
                string refProject2 = this.CreateTempFile("csproj", refProject2Contents);
                string refProject3 = this.CreateTempFile("csproj", refProject2Contents);

                string projectContents = string.Format(@"
<Project ToolsVersion=""4.0"" DefaultTargets=""Build"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
  <ItemGroup>
    <ProjectReference Include=""{0}""></ProjectReference>
    <ProjectReference Include=""{1}""></ProjectReference>
    <ProjectReference Include=""{2}""></ProjectReference>
  </ItemGroup>
</Project>", refProject1, refProject2, refProject3);

                string projectFile = this.CreateTempFile("csproj", projectContents);
                string historyFile = this.CreateTempFile("txt", null);  // <-- null prevents us from creating file on disk
                try
                {
                    LinkedServerProjectCache cache = new LinkedServerProjectCache(projectFile, historyFile, logger, projectFileReader);

                    // Validate we see our 3 project references
                    List <string> projectRefs = cache.ProjectReferences.ToList();
                    Assert.AreEqual(3, projectRefs.Count, "Expected this many project references");
                    Assert.IsTrue(projectRefs.Contains(refProject1), "Expected ref project 1 in project references.");
                    Assert.IsTrue(projectRefs.Contains(refProject2), "Expected ref project 2 in project references.");
                    Assert.IsTrue(projectRefs.Contains(refProject3), "Expected ref project 3 in project references.");

                    // Validate that we extracted the RIA Links for those project references
                    List <string> riaLinks = cache.LinkedServerProjects.ToList();
                    Assert.AreEqual(2, riaLinks.Count, "Expected to find 2 RIA links");
                    Assert.IsTrue(riaLinks.Contains(serverProject1), "Expected server project 1 RIA link");
                    Assert.IsTrue(riaLinks.Contains(serverProject2), "Expected server project 2 RIA link");

                    // Validate that we can ask for the source of each RIA Link target
                    List <string> sources = cache.GetLinkedServerProjectSources(serverProject1).ToList();
                    Assert.AreEqual(1, sources.Count, "Expected 1 source to for RIA link to server project 1");
                    Assert.IsTrue(sources.Contains(refProject1), "Expected refProject 1 to be shown as RIA Link source 1");

                    sources = cache.GetLinkedServerProjectSources(serverProject2).ToList();
                    Assert.AreEqual(2, sources.Count, "Expected 2 sources to for RIA link to server project 2");
                    Assert.IsTrue(sources.Contains(refProject2), "Expected refProject 2 to be shown as RIA Link source 2");
                    Assert.IsTrue(sources.Contains(refProject3), "Expected refProject 2 to be shown as RIA Link source 2");
                }
                finally
                {
                    File.Delete(projectFile);
                    File.Delete(historyFile);
                    File.Delete(refProject1);
                    File.Delete(refProject2);
                    File.Delete(refProject3);
                    File.Delete(serverProject1);
                    File.Delete(serverProject2);
                }
            }
        }