Skip to content

Commit

Permalink
docs: add XML documentation comments to public API (#93)
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas-Shephard authored Oct 22, 2024
1 parent 8ca543b commit b63c84f
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 0 deletions.
21 changes: 21 additions & 0 deletions src/CoverageChecker/CoverageAnalyser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,29 @@

namespace CoverageChecker;

/// <summary>
/// Analyses coverage information
/// </summary>
public class CoverageAnalyser {
private readonly CoverageFormat _coverageFormat;
private readonly string _directory;
private readonly string[] _globPatterns;

/// <summary>
/// Initializes a new instance of the <see cref="CoverageAnalyser"/> class with a single glob pattern.
/// </summary>
/// <param name="coverageFormat">The format of the coverage file.</param>
/// <param name="directory">The directory to search for coverage files within.</param>
/// <param name="globPattern">The glob pattern to use to search for coverage files.</param>
public CoverageAnalyser(CoverageFormat coverageFormat, string directory, string globPattern) : this(coverageFormat, directory, [globPattern]) { }

/// <summary>
/// Initializes a new instance of the <see cref="CoverageAnalyser"/> class with multiple glob patterns.
/// </summary>
/// <param name="coverageFormat">The format of the coverage file.</param>
/// <param name="directory">The directory to search for coverage files within.</param>
/// <param name="globPatterns">The glob patterns to use to search for coverage files.</param>
/// <exception cref="ArgumentException">Thrown when no glob patterns are provided.</exception>
public CoverageAnalyser(CoverageFormat coverageFormat, string directory, IEnumerable<string> globPatterns) {
globPatterns = globPatterns.ToArray();

Expand All @@ -23,6 +39,11 @@ public CoverageAnalyser(CoverageFormat coverageFormat, string directory, IEnumer
_globPatterns = globPatterns.ToArray();
}

/// <summary>
/// Analyses the coverage information from the given glob patterns in the specified directory.
/// </summary>
/// <returns>The coverage information.</returns>
/// <exception cref="NoCoverageFilesFoundException">Thrown when no coverage files are found.</exception>
public Coverage AnalyseCoverage() {
string[] filePaths = GlobUtils.GetFilePathsFromGlobPatterns(_directory, _globPatterns).ToArray();

Expand Down
3 changes: 3 additions & 0 deletions src/CoverageChecker/CoverageFormat.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
namespace CoverageChecker;

/// <summary>
/// The format of the coverage report.
/// </summary>
public enum CoverageFormat {
Cobertura,
SonarQube
Expand Down
3 changes: 3 additions & 0 deletions src/CoverageChecker/CoverageType.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
namespace CoverageChecker;

/// <summary>
/// The type of code coverage to calculate.
/// </summary>
public enum CoverageType {
Line,
Branch
Expand Down
12 changes: 12 additions & 0 deletions src/CoverageChecker/Exceptions.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
namespace CoverageChecker;

/// <summary>
/// Base class for all custom exceptions thrown by this package.
/// </summary>
public abstract class CoverageException : Exception {
protected CoverageException() { }
protected CoverageException(string message) : base(message) { }
protected CoverageException(string message, Exception innerException) : base(message, innerException) { }
}

/// <summary>
/// Thrown when no coverage files are found during analysis.
/// </summary>
public class NoCoverageFilesFoundException : CoverageException {
internal NoCoverageFilesFoundException() { }
}

/// <summary>
/// Thrown when a coverage calculation cannot be performed.
/// </summary>
public class CoverageCalculationException : CoverageException {
internal CoverageCalculationException(string message) : base(message) { }
}

/// <summary>
/// Thrown when a coverage file cannot be parsed.
/// </summary>
public class CoverageParseException : CoverageException {
internal CoverageParseException(string message) : base(message) { }
internal CoverageParseException(string message, Exception innerException) : base(message, innerException) { }
Expand Down
18 changes: 18 additions & 0 deletions src/CoverageChecker/Results/Coverage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@

namespace CoverageChecker.Results;

/// <summary>
/// Represents coverage information for a collection of files.
/// </summary>
public class Coverage {
/// <summary>
/// The files that coverage information has been obtained for.
/// </summary>
public IReadOnlyList<FileCoverage> Files => _files.AsReadOnly();
private readonly List<FileCoverage> _files = [];

Expand All @@ -25,10 +31,22 @@ internal FileCoverage GetOrCreateFile(string filePath, string? packageName = nul
return file;
}

/// <summary>
/// Calculates the coverage for all files.
/// </summary>
/// <param name="coverageType">The type of coverage to calculate. Defaults to <see cref="CoverageType.Line"/>.</param>
/// <returns>The coverage for all files.</returns>
public double CalculateOverallCoverage(CoverageType coverageType = CoverageType.Line) {
return _files.CalculateCoverage(coverageType);
}

/// <summary>
/// Calculates the coverage for all files that are part of the specified package.
/// </summary>
/// <param name="packageName">The name of the package to filter by.</param>
/// <param name="coverageType">The type of coverage to calculate. Defaults to <see cref="CoverageType.Line"/>.</param>
/// <returns>The coverage for all files that are part of the specified package.</returns>
/// <exception cref="CoverageCalculationException">Thrown when no files are found that are part of the specified package.</exception>
public double CalculatePackageCoverage(string packageName, CoverageType coverageType = CoverageType.Line) {
FileCoverage[] filteredFiles = _files.Where(file => file.PackageName == packageName)
.ToArray();
Expand Down
33 changes: 33 additions & 0 deletions src/CoverageChecker/Results/FileCoverage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,22 @@

namespace CoverageChecker.Results;

/// <summary>
/// Represents coverage information for a single file.
/// </summary>
public class FileCoverage {
/// <summary>
/// The path of the file.
/// </summary>
public string Path { get; }
/// <summary>
/// The name of the package the file is part of.
/// If null, the file is not part of a package.
/// </summary>
public string? PackageName { get; }
/// <summary>
/// The lines within the file.
/// </summary>
public IReadOnlyList<LineCoverage> Lines => _lines.AsReadOnly();
private readonly List<LineCoverage> _lines = [];

Expand All @@ -28,10 +41,22 @@ internal void AddLine(int lineNumber, bool isCovered, int? branches = null, int?
}
}

/// <summary>
/// Calculates the coverage for the file.
/// </summary>
/// <param name="coverageType">The type of coverage to calculate. Defaults to <see cref="CoverageType.Line"/>.</param>
/// <returns>The coverage for the file.</returns>
public double CalculateFileCoverage(CoverageType coverageType = CoverageType.Line) {
return _lines.CalculateCoverage(coverageType);
}

/// <summary>
/// Calculates the coverage for all lines that are part of the specified class.
/// </summary>
/// <param name="className">The name of the class to filter by.</param>
/// <param name="coverageType">The type of coverage to calculate. Defaults to <see cref="CoverageType.Line"/>.</param>
/// <returns>The coverage for all lines that are part of the specified class.</returns>
/// <exception cref="CoverageCalculationException">Thrown when no lines are found that are part of the specified class.</exception>
public double CalculateClassCoverage(string className, CoverageType coverageType = CoverageType.Line) {
LineCoverage[] filteredLines = _lines.Where(line => line.ClassName == className)
.ToArray();
Expand All @@ -42,6 +67,14 @@ public double CalculateClassCoverage(string className, CoverageType coverageType
return filteredLines.CalculateCoverage(coverageType);
}

/// <summary>
/// Calculates the coverage for all lines that are part of the specified method.
/// </summary>
/// <param name="methodName">The name of the method to filter by.</param>
/// <param name="methodSignature">Optionally, the signature of the method to filter by. If null, only the method name is checked.</param>
/// <param name="coverageType">The type of coverage to calculate. Defaults to <see cref="CoverageType.Line"/>.</param>
/// <returns>The coverage for all lines that are part of the specified method.</returns>
/// <exception cref="CoverageCalculationException">Thrown when no lines are found that are part of the specified method.</exception>
public double CalculateMethodCoverage(string methodName, string? methodSignature = null, CoverageType coverageType = CoverageType.Line) {
LineCoverage[] filteredLines = _lines.Where(line => {
// If the method signature is null, only the method name is checked
Expand Down
35 changes: 35 additions & 0 deletions src/CoverageChecker/Results/LineCoverage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,43 @@

namespace CoverageChecker.Results;

/// <summary>
/// Represents coverage information for a single line within a file.
/// </summary>
public class LineCoverage {
/// <summary>
/// The line number.
/// </summary>
public int LineNumber { get; }
/// <summary>
/// Whether the line is covered.
/// If true, the line has been covered, otherwise, false.
/// </summary>
public bool IsCovered { get; private set; }
/// <summary>
/// The number of branches in the line.
/// If null, the line does not have any branches.
/// </summary>
public int? Branches { get; private set; }
/// <summary>
/// The number of covered branches in the line.
/// If null, the line does not have any branches.
/// </summary>
public int? CoveredBranches { get; private set; }
/// <summary>
/// The name of the class the line is part of.
/// If null, the line is not part of a class.
/// </summary>
public string? ClassName { get; }
/// <summary>
/// The name of the method the line is part of.
/// If null, the line is not part of a method.
/// </summary>
public string? MethodName { get; }
/// <summary>
/// The method signature of the method the line is part of.
/// If null, the line is not part of a method or the method does not have a method signature.
/// </summary>
public string? MethodSignature { get; }

internal LineCoverage(int lineNumber, bool isCovered, int? branches = null, int? coveredBranches = null, string? className = null, string? methodName = null, string? methodSignature = null) {
Expand All @@ -34,6 +64,11 @@ internal LineCoverage(int lineNumber, bool isCovered, int? branches = null, int?
MethodSignature = methodSignature;
}

/// <summary>
/// Calculates the coverage for this line.
/// </summary>
/// <param name="coverageType">The type of coverage to calculate. Defaults to <see cref="CoverageType.Line"/>.</param>
/// <returns>The coverage for this line.</returns>
public double CalculateLineCoverage(CoverageType coverageType = CoverageType.Line) {
LineCoverage[] lines = [this];

Expand Down

0 comments on commit b63c84f

Please sign in to comment.