< Summary

Information
Class: DotNetApiDiff.Models.ApiChange
Assembly: DotNetApiDiff
File(s): /home/runner/work/dotnet-api-diff/dotnet-api-diff/src/DotNetApiDiff/Models/ApiChange.cs
Line coverage
93%
Covered lines: 31
Uncovered lines: 2
Coverable lines: 33
Total lines: 99
Line coverage: 93.9%
Branch coverage
97%
Covered branches: 33
Total branches: 34
Branch coverage: 97%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Type()100%11100%
get_SourceMember()100%11100%
get_TargetMember()100%11100%
get_IsBreakingChange()100%11100%
get_Description()100%11100%
get_Details()100%11100%
IsValid()95.83%252489.47%
GetMemberName()100%88100%
ToString()100%22100%

File(s)

/home/runner/work/dotnet-api-diff/dotnet-api-diff/src/DotNetApiDiff/Models/ApiChange.cs

#LineLine coverage
 1// Copyright DotNet API Diff Project Contributors - SPDX Identifier: MIT
 2using System.ComponentModel.DataAnnotations;
 3
 4namespace DotNetApiDiff.Models;
 5
 6/// <summary>
 7/// Represents a change detected between two API members
 8/// </summary>
 9public class ApiChange
 10{
 11    /// <summary>
 12    /// Type of change (Added, Removed, Modified, Excluded)
 13    /// </summary>
 14014    public ChangeType Type { get; set; }
 15
 16    /// <summary>
 17    /// The source member (from the original assembly)
 18    /// </summary>
 4219    public ApiMember? SourceMember { get; set; }
 20
 21    /// <summary>
 22    /// The target member (from the new assembly)
 23    /// </summary>
 4924    public ApiMember? TargetMember { get; set; }
 25
 26    /// <summary>
 27    /// Whether this change is considered breaking
 28    /// </summary>
 5629    public bool IsBreakingChange { get; set; }
 30
 31    /// <summary>
 32    /// Human-readable description of the change
 33    /// </summary>
 34    [Required]
 12635    public string Description { get; set; } = string.Empty;
 36
 37    /// <summary>
 38    /// Additional details about the change
 39    /// </summary>
 7440    public List<string> Details { get; set; } = new List<string>();
 41
 42    /// <summary>
 43    /// Validates the ApiChange instance
 44    /// </summary>
 45    /// <returns>True if valid, false otherwise</returns>
 46    public bool IsValid()
 2147    {
 48        // Must have a description
 2149        if (string.IsNullOrWhiteSpace(Description))
 250        {
 251            return false;
 52        }
 53
 54        // Must have at least one member for most change types
 1955        if (Type != ChangeType.Added && Type != ChangeType.Removed &&
 1956            SourceMember == null && TargetMember == null)
 057        {
 058            return false;
 59        }
 60
 61        // Added changes should have target member
 1962        if (Type == ChangeType.Added && TargetMember == null)
 463        {
 464            return false;
 65        }
 66
 67        // Removed changes should have source member
 1568        if (Type == ChangeType.Removed && SourceMember == null)
 269        {
 270            return false;
 71        }
 72
 73        // Modified changes should have both members
 1374        if (Type == ChangeType.Modified && (SourceMember == null || TargetMember == null))
 275        {
 276            return false;
 77        }
 78
 1179        return true;
 2180    }
 81
 82    /// <summary>
 83    /// Gets the primary member name for this change
 84    /// </summary>
 85    public string GetMemberName()
 586    {
 587        return TargetMember?.FullName ?? SourceMember?.FullName ?? "Unknown";
 588    }
 89
 90    /// <summary>
 91    /// Gets a string representation of the change
 92    /// </summary>
 93    public override string ToString()
 294    {
 295        var memberName = GetMemberName();
 296        var breakingIndicator = IsBreakingChange ? " [BREAKING]" : string.Empty;
 297        return $"{Type}: {memberName}{breakingIndicator}";
 298    }
 99}