|
| 1 | +# AngleSharp.Diffing - HTML Comparison Library |
| 2 | + |
| 3 | +AngleSharp.Diffing is a .NET library for comparing AngleSharp control nodes and test nodes to identify differences between HTML DOM trees. This library targets .NET Standard 2.0 and provides a fluent API for HTML comparison and diffing. |
| 4 | + |
| 5 | +**Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.** |
| 6 | + |
| 7 | +## Working Effectively |
| 8 | + |
| 9 | +### Prerequisites and Setup |
| 10 | +- Install .NET 8.0+ SDK (already available in GitHub Actions environments) |
| 11 | +- Mono is NOT required for standard development (only for legacy Cake build system) |
| 12 | + |
| 13 | +### Bootstrap, Build, and Test |
| 14 | +Execute these commands in order from the repository root: |
| 15 | + |
| 16 | +```bash |
| 17 | +cd src |
| 18 | +dotnet restore # ~11 seconds - restores NuGet packages |
| 19 | +dotnet build # ~15 seconds - compiles library and tests |
| 20 | +dotnet test # ~5 seconds - runs 521 tests. NEVER CANCEL. |
| 21 | +``` |
| 22 | + |
| 23 | +**CRITICAL TIMING EXPECTATIONS:** |
| 24 | +- `dotnet restore`: 11 seconds - NEVER CANCEL. Set timeout to 60+ seconds minimum. |
| 25 | +- `dotnet build`: 15 seconds - NEVER CANCEL. Set timeout to 60+ seconds minimum. |
| 26 | +- `dotnet test`: 5 seconds - runs 521 tests. NEVER CANCEL. Set timeout to 30+ seconds minimum. |
| 27 | +- Complete clean rebuild: ~20 seconds - NEVER CANCEL. Set timeout to 60+ seconds minimum. |
| 28 | + |
| 29 | +### Alternative Build Methods |
| 30 | +**PRIMARY METHOD (Recommended):** Use dotnet CLI commands as shown above. |
| 31 | + |
| 32 | +**LEGACY METHOD (Not Recommended):** The repository includes Cake build scripts (`build.sh`/`build.ps1`) but they require Mono and may fail. Only use if specifically needed: |
| 33 | +```bash |
| 34 | +# Install Mono first (if needed) |
| 35 | +sudo apt-get update && sudo apt-get install -y mono-complete |
| 36 | +./build.sh # May fail - use dotnet commands instead |
| 37 | +``` |
| 38 | + |
| 39 | +### Release Builds and Packaging |
| 40 | +```bash |
| 41 | +cd src |
| 42 | +dotnet build --configuration Release # ~15 seconds |
| 43 | +dotnet pack --configuration Release # ~8 seconds - creates NuGet packages |
| 44 | +``` |
| 45 | + |
| 46 | +**Package Output:** Creates `.nupkg` and `.snupkg` files in `src/AngleSharp.Diffing/bin/Release/` |
| 47 | + |
| 48 | +## Validation and Testing |
| 49 | + |
| 50 | +### Manual Validation Requirements |
| 51 | +**ALWAYS** validate changes by creating and running a test program to exercise the library: |
| 52 | + |
| 53 | +```csharp |
| 54 | +using AngleSharp.Diffing; |
| 55 | + |
| 56 | +// Test basic HTML diffing functionality |
| 57 | +var control = @"<p attr=""foo"">hello <em>world</em></p>"; |
| 58 | +var test = @"<p attr=""bar"">hello <strong>world</strong></p>"; |
| 59 | + |
| 60 | +var diffs = DiffBuilder |
| 61 | + .Compare(control) |
| 62 | + .WithTest(test) |
| 63 | + .Build() |
| 64 | + .ToList(); |
| 65 | + |
| 66 | +Console.WriteLine($"Found {diffs.Count} differences:"); |
| 67 | +foreach (var diff in diffs) |
| 68 | +{ |
| 69 | + Console.WriteLine($"- {diff.GetType().Name}: {diff.Result} {diff.Target}"); |
| 70 | +} |
| 71 | +``` |
| 72 | + |
| 73 | +### Code Quality and Standards |
| 74 | +- **Code Analysis:** Project has strict analysis rules enabled (`EnforceCodeStyleInBuild=true`) |
| 75 | +- **EditorConfig:** Follow the existing `.editorconfig` settings (4-space indentation, CRLF line endings) |
| 76 | +- **Nullable References:** Enabled - handle null values appropriately |
| 77 | +- **Build Warnings:** Zero warnings expected - treat warnings as errors for critical types |
| 78 | + |
| 79 | +### Test Suite Information |
| 80 | +- **Test Framework:** xUnit with Shouldly assertions |
| 81 | +- **Test Count:** 521 tests covering core diffing functionality |
| 82 | +- **Test Runtime:** ~5 seconds total |
| 83 | +- **Test Files Location:** `src/AngleSharp.Diffing.Tests/` |
| 84 | + |
| 85 | +## Navigation and Architecture |
| 86 | + |
| 87 | +### Key Directories and Files |
| 88 | +``` |
| 89 | +src/ |
| 90 | +├── AngleSharp.Diffing/ # Main library project |
| 91 | +│ ├── Core/ # Core diffing engine and interfaces |
| 92 | +│ ├── Extensions/ # Extension methods |
| 93 | +│ ├── Strategies/ # Diffing strategy implementations |
| 94 | +│ └── DiffBuilder.cs # Main fluent API entry point |
| 95 | +├── AngleSharp.Diffing.Tests/ # Test project |
| 96 | +│ ├── Core/ # Core functionality tests |
| 97 | +│ └── Strategies/ # Strategy-specific tests |
| 98 | +└── AngleSharp.Diffing.sln # Solution file |
| 99 | +``` |
| 100 | + |
| 101 | +### Important Classes and APIs |
| 102 | +- **`DiffBuilder`**: Main entry point with fluent API (`DiffBuilder.Compare(control).WithTest(test).Build()`) |
| 103 | +- **`IDiff`**: Base interface for all difference types |
| 104 | +- **`HtmlDifferenceEngine`**: Core comparison engine |
| 105 | +- **Diff Types**: `AttrDiff`, `NodeDiff`, `MissingNodeDiff`, `UnexpectedNodeDiff`, etc. |
| 106 | + |
| 107 | +### Dependencies |
| 108 | +- **AngleSharp 1.1.2**: Core HTML parsing library |
| 109 | +- **AngleSharp.Css 1.0.0-beta.144**: CSS support |
| 110 | +- **Target Framework**: .NET Standard 2.0 (library), .NET 8.0 (tests) |
| 111 | + |
| 112 | +## Common Development Tasks |
| 113 | + |
| 114 | +### Making Code Changes |
| 115 | +1. **Always build and test first** to establish baseline: `dotnet build && dotnet test` |
| 116 | +2. Make your changes to source files in `src/AngleSharp.Diffing/` |
| 117 | +3. **Immediately test after changes**: `dotnet build && dotnet test` |
| 118 | +4. **Manual validation**: Create a test program to exercise your changes |
| 119 | +5. **Pre-commit validation**: Ensure no build warnings or test failures |
| 120 | + |
| 121 | +### Debugging and Investigation |
| 122 | +- **Test filtering**: `dotnet test --filter "TestMethodName"` to run specific tests |
| 123 | +- **Verbose builds**: `dotnet build --verbosity normal` to see detailed output |
| 124 | +- **Key test files**: `DiffBuilderTest.cs` shows basic API usage patterns |
| 125 | + |
| 126 | +### CI/Build Requirements |
| 127 | +- **GitHub Actions**: Runs on both Linux and Windows |
| 128 | +- **Zero warnings policy**: Build must complete without warnings |
| 129 | +- **All tests must pass**: 521/521 tests required |
| 130 | +- **Code formatting**: Enforced via EditorConfig and analyzers |
| 131 | + |
| 132 | +## Getting Started Examples |
| 133 | + |
| 134 | +### Basic HTML Comparison |
| 135 | +```csharp |
| 136 | +var control = "<p>Expected content</p>"; |
| 137 | +var test = "<p>Actual content</p>"; |
| 138 | + |
| 139 | +var diffs = DiffBuilder |
| 140 | + .Compare(control) |
| 141 | + .WithTest(test) |
| 142 | + .Build(); |
| 143 | +``` |
| 144 | + |
| 145 | +### Advanced Configuration |
| 146 | +```csharp |
| 147 | +var diffs = DiffBuilder |
| 148 | + .Compare(control) |
| 149 | + .WithTest(test) |
| 150 | + .WithOptions(options => { |
| 151 | + // Configure diffing strategies |
| 152 | + }) |
| 153 | + .Build(); |
| 154 | +``` |
| 155 | + |
| 156 | +### Working with Results |
| 157 | +```csharp |
| 158 | +foreach (var diff in diffs) |
| 159 | +{ |
| 160 | + switch (diff.Result) |
| 161 | + { |
| 162 | + case DiffResult.Different: |
| 163 | + case DiffResult.Missing: |
| 164 | + case DiffResult.Unexpected: |
| 165 | + // Handle different types of differences |
| 166 | + break; |
| 167 | + } |
| 168 | +} |
| 169 | +``` |
| 170 | + |
| 171 | +## Troubleshooting |
| 172 | + |
| 173 | +### Common Issues |
| 174 | +- **Build failures**: Ensure you're in the `src/` directory |
| 175 | +- **Cake build failures**: Use `dotnet` commands instead of `build.sh`/`build.ps1` |
| 176 | +- **Test failures**: Check for environment-specific issues or recent changes |
| 177 | +- **Package restore issues**: Clear NuGet caches with `dotnet nuget locals all --clear` |
| 178 | + |
| 179 | +### Quick Reset Commands |
| 180 | +```bash |
| 181 | +# Clean and rebuild everything |
| 182 | +cd src |
| 183 | +dotnet clean |
| 184 | +rm -rf */bin */obj |
| 185 | +dotnet restore |
| 186 | +dotnet build |
| 187 | +dotnet test |
| 188 | +``` |
| 189 | + |
| 190 | +## Performance Expectations |
| 191 | +- **Development builds**: ~15 seconds |
| 192 | +- **Test execution**: ~5 seconds for full suite |
| 193 | +- **Package creation**: ~8 seconds |
| 194 | +- **CI builds**: Allow 60+ seconds timeout minimum for each step |
| 195 | + |
| 196 | +**CRITICAL**: NEVER CANCEL builds or tests that appear slow. Wait at least 60 seconds for builds and 30 seconds for tests before considering alternatives. |
0 commit comments