public void AddFile_AddSingleFile_FileIsStored() { var assembly = new Assembly("C:\\test\\TestAssembly.dll"); var sut = new Class("Test", assembly); var file = new CodeFile("C:\\temp\\Program.cs", new int[0]); sut.AddFile(file); Assert.AreEqual(file, sut.Files.First(), "Not equal"); Assert.AreEqual(1, sut.Files.Count(), "Wrong number of classes"); }
public void Merge_MergeClassWithOneFileAndOneMethodMetric_FileIsStored() { var assembly = new Assembly("C:\\test\\TestAssembly.dll"); var sut = new Class("Test", assembly); var classToMerge = new Class("Test", assembly); var file = new CodeFile("C:\\temp\\Program.cs", new int[0]); var methodMetric = new MethodMetric("Test"); classToMerge.AddFile(file); classToMerge.AddMethodMetric(methodMetric); sut.Merge(classToMerge); Assert.AreEqual(file, sut.Files.First(), "Not equal"); Assert.AreEqual(1, sut.Files.Count(), "Wrong number of classes"); Assert.AreEqual(methodMetric, sut.MethodMetrics.First(), "Not equal"); Assert.AreEqual(1, sut.MethodMetrics.Count(), "Wrong number of method metrics"); }
/// <summary> /// Processes the given class. /// </summary> /// <param name="assembly">The assembly.</param> /// <param name="className">Name of the class.</param> /// <returns>The <see cref="Class"/>.</returns> private Class ProcessClass(Assembly assembly, string className) { var filesOfClass = this.modules .Where(module => module.Attribute("assembly").Value.Equals(assembly.Name)).Elements("method") .Where(method => method.Attribute("class").Value.Equals(className)) .Where(m => m.Attribute("excluded").Value == "false") .Elements("seqpnt").Select(seqpnt => seqpnt.Attribute("document").Value) .Distinct() .ToArray(); var @class = new Class(className, assembly); foreach (var file in filesOfClass) { @class.AddFile(this.ProcessFile(@class, file)); } return @class; }
/// <summary> /// Processes the given class. /// </summary> /// <param name="fileIdsByFilename">Dictionary containing the file ids by filename.</param> /// <param name="assembly">The assembly.</param> /// <param name="className">Name of the class.</param> /// <returns>The <see cref="Class"/>.</returns> private Class ProcessClass(Dictionary<string, HashSet<string>> fileIdsByFilename, Assembly assembly, string className) { var methods = this.modules .Where(m => m.Element("ModuleName").Value.Equals(assembly.Name)) .Elements("Classes") .Elements("Class") .Where(c => c.Element("FullName").Value.Equals(className) || c.Element("FullName").Value.StartsWith(className + "/", StringComparison.Ordinal)) .Elements("Methods") .Elements("Method"); var fileIdsOfClassInSequencePoints = methods .Elements("SequencePoints") .Elements("SequencePoint") .Where(seqpnt => seqpnt.Attribute("fileid") != null && seqpnt.Attribute("fileid").Value != "0") .Select(seqpnt => seqpnt.Attribute("fileid").Value) .ToArray(); // Only required for backwards compatibility, older versions of OpenCover did not apply fileid for partial classes var fileIdsOfClassInFileRef = methods .Where(m => m.Element("FileRef") != null) .Select(m => m.Element("FileRef").Attribute("uid").Value) .ToArray(); var fileIdsOfClass = fileIdsOfClassInSequencePoints .Concat(fileIdsOfClassInFileRef) .Distinct() .ToHashSet(); var filesOfClass = this.files .Where(file => fileIdsOfClass.Contains(file.Attribute("uid").Value)) .Select(file => file.Attribute("fullPath").Value) .Distinct() .ToArray(); var @class = new Class(className, assembly); foreach (var file in filesOfClass) { @class.AddFile(this.ProcessFile(fileIdsByFilename[file], @class, file)); } @class.CoverageQuota = this.GetCoverageQuotaOfClass(assembly, className); return @class; }
/// <summary> /// Processes the given class. /// </summary> /// <param name="assembly">The assembly.</param> /// <param name="className">Name of the class.</param> /// <returns>The <see cref="Class"/>.</returns> private Class ProcessClass(Assembly assembly, string className) { var fileIdsOfClass = this.types .Where(type => type.Attribute("asm").Value.Equals(assembly.Name) && (type.Attribute("name").Value.Equals(className, StringComparison.Ordinal) || type.Attribute("name").Value.StartsWith(className + "<", StringComparison.Ordinal))) .Elements("method") .Elements("code") .Elements("pt") .Where(pt => pt.Attribute("fid") != null) .Select(pt => pt.Attribute("fid").Value) .Distinct() .ToHashSet(); var filesOfClass = this.files .Where(file => fileIdsOfClass.Contains(file.Attribute("id").Value)) .Select(file => file.Attribute("url").Value) .ToArray(); var @class = new Class(className, assembly); foreach (var file in filesOfClass) { @class.AddFile(this.ProcessFile(@class, file)); } return @class; }
/// <summary> /// Processes the given class. /// </summary> /// <param name="module">The module.</param> /// <param name="assembly">The assembly.</param> /// <param name="className">Name of the class.</param> /// <returns>The <see cref="Class"/>.</returns> private static Class ProcessClass(XElement module, Assembly assembly, string className) { var fileIdsOfClass = module .Elements("functions") .Elements("function") .Where(c => c.Attribute("type_name").Value.Equals(className, StringComparison.Ordinal) || c.Attribute("type_name").Value.StartsWith(className + ".", StringComparison.Ordinal)) .Elements("ranges") .Elements("range") .Select(r => r.Attribute("source_id").Value) .Distinct(); var @class = new Class(className, assembly); var files = module.Elements("source_files").Elements("source_file"); foreach (var fileId in fileIdsOfClass) { string file = files.First(f => f.Attribute("id").Value == fileId).Attribute("path").Value; @class.AddFile(ProcessFile(module, fileId, @class, file)); } return @class; }
/// <summary> /// Processes the given class. /// </summary> /// <param name="assembly">The assembly.</param> /// <param name="className">Name of the class.</param> /// <returns>The <see cref="Class"/>.</returns> private Class ProcessClass(Assembly assembly, string className) { var fileIdsOfClass = this.modules .Where(m => m.Element("ModuleName").Value.Equals(assembly.Name)) .Elements("NamespaceTable") .Elements("Class") .Where(c => (c.Parent.Element("NamespaceName").Value + "." + c.Element("ClassName").Value).Equals(className, StringComparison.Ordinal) || (c.Parent.Element("NamespaceName").Value + "." + c.Element("ClassName").Value).StartsWith(className + ".", StringComparison.Ordinal)) .Elements("Method") .Elements("Lines") .Elements("SourceFileID") .Select(m => m.Value) .Distinct(); var @class = new Class(className, assembly); foreach (var fileId in fileIdsOfClass) { string file = this.files.First(f => f.Element("SourceFileID").Value == fileId).Element("SourceFileName").Value; @class.AddFile(this.ProcessFile(fileId, @class, file)); } return @class; }
/// <summary> /// Processes the given class. /// </summary> /// <param name="assembly">The assembly.</param> /// <param name="className">Name of the class.</param> /// <returns>The <see cref="Class"/>.</returns> private Class ProcessClass(Assembly assembly, string className) { var fileIdsOfClass = this.types .Where(type => this.assembliesByIdDictionary[type.Attribute(this.assemblyAttribute).Value].Equals(assembly.Name) && type.Attribute("name").Value.Equals(className)) .Elements("Method") .Elements("pt") .Where(pt => pt.Attribute("fid") != null) .Select(pt => pt.Attribute("fid").Value) .Distinct().ToHashSet(); var filesOfClass = this.files .Where(file => fileIdsOfClass.Contains(file.Attribute("id").Value)) .Select(file => file.Attribute("url").Value) .ToArray(); var @class = new Class(className, assembly); foreach (var file in filesOfClass) { @class.AddFile(this.ProcessFile(@class, file)); } return @class; }
/// <summary> /// Processes the given class. /// </summary> /// <param name="assembly">The assembly.</param> /// <param name="className">Name of the class.</param> /// <returns>The <see cref="Class"/>.</returns> private Class ProcessClass(Assembly assembly, string className) { var assemblyElement = this.modules .Where(m => m.Attribute("Name").Value.Equals(assembly.Name)); var filesIdsOfClass = assemblyElement .Elements("Namespace") .Elements("Type") .Concat(assemblyElement.Elements("Type")) .Where(c => (c.Parent.Attribute("Name").Value + "." + c.Attribute("Name").Value).Equals(className)) .Descendants("Statement") .Select(c => c.Attribute("FileIndex").Value) .Distinct() .ToArray(); var @class = new Class(className, assembly); foreach (var fileId in filesIdsOfClass) { @class.AddFile(this.ProcessFile(fileId, @class)); } return @class; }
/// <summary> /// Processes the given class. /// </summary> /// <param name="fileIdsByFilename">Dictionary containing the file ids by filename.</param> /// <param name="assembly">The assembly.</param> /// <param name="className">Name of the class.</param> /// <returns>The <see cref="Class"/>.</returns> private Class ProcessClass(Dictionary<string, HashSet<string>> fileIdsByFilename, Assembly assembly, string className) { var fileIdsOfClass = this.modules .Where(m => m.Element("ModuleName").Value.Equals(assembly.Name)) .Elements("Classes") .Elements("Class") .Where(c => c.Element("FullName").Value.Equals(className)) .Elements("Methods") .Elements("Method") .Where(m => m.Element("FileRef") != null) .Select(m => m.Element("FileRef").Attribute("uid").Value) .Distinct() .ToHashSet(); var filesOfClass = this.files .Where(file => fileIdsOfClass.Contains(file.Attribute("uid").Value)) .Select(file => file.Attribute("fullPath").Value) .Distinct() .ToArray(); var @class = new Class(className, assembly); foreach (var file in filesOfClass) { @class.AddFile(this.ProcessFile(fileIdsByFilename[file], @class, file)); } @class.CoverageQuota = this.GetCoverageQuotaOfClass(assembly, className); return @class; }
private IEnumerable<Class> ProcessClasses(Assembly rootAssembly, IEnumerable<CoverageLine> lines) { var classes = lines.GroupBy (x => x.TypeName); foreach (var classData in classes) { if (classData.Key.StartsWith ("<>__AnonType")) continue; Class classEntry = new Class (classData.Key, rootAssembly); var totalNum = classData.Count (); var hit = classData.Count (x => !x.Missed); classEntry.CoverageQuota = hit / totalNum; foreach (var codeFile in ProcessFiles (classEntry, classData.ToList())) classEntry.AddFile (codeFile); yield return classEntry; } }