|
| 1 | +using System; |
| 2 | +using System.Collections.Generic; |
| 3 | +using System.Linq; |
| 4 | +using System.Text; |
| 5 | +using System.Text.RegularExpressions; |
| 6 | +using System.Threading.Tasks; |
| 7 | +using System.Xml; |
| 8 | +using Egil.RazorComponents.Testing.Rendering; |
| 9 | +using Org.XmlUnit.Diff; |
| 10 | + |
| 11 | +namespace Egil.RazorComponents.Testing.Diffing |
| 12 | +{ |
| 13 | + public static class HtmlDifferenceEvaluators |
| 14 | + { |
| 15 | + private const string RegexNamespace = RenderedFactXmlDocumentExtensions.RegexXmlNamespace; |
| 16 | + private readonly static char[] Space = new char[] { ' ' }; |
| 17 | + |
| 18 | + public static ComparisonResult RegexAttributeDifferenceEvaluator(Comparison comparison, ComparisonResult outcome) |
| 19 | + { |
| 20 | + if (comparison is null) throw new ArgumentNullException(nameof(comparison)); |
| 21 | + |
| 22 | + if (outcome == ComparisonResult.EQUAL) return outcome; |
| 23 | + if (comparison.Type != ComparisonType.ATTR_NAME_LOOKUP) return outcome; |
| 24 | + |
| 25 | + if (comparison.ControlDetails.Value is XmlQualifiedName a1 && a1.Namespace == RegexNamespace) |
| 26 | + { |
| 27 | + var testAttr = comparison.TestDetails.Target.Attributes.GetNamedItem(a1.Name); |
| 28 | + var ctrlAttr = comparison.ControlDetails.Target.Attributes.GetNamedItem(a1.Name, a1.Namespace); |
| 29 | + if (Regex.IsMatch(testAttr.Value, ctrlAttr.Value)) |
| 30 | + { |
| 31 | + return ComparisonResult.EQUAL; |
| 32 | + } |
| 33 | + } |
| 34 | + else if (comparison.TestDetails.Value is XmlQualifiedName a2 && comparison.ControlDetails.Target.Attributes.GetNamedItem(a2.Name, RegexNamespace) is XmlNode ctrlAttr) |
| 35 | + { |
| 36 | + return ComparisonResult.EQUAL; |
| 37 | + } |
| 38 | + return outcome; |
| 39 | + } |
| 40 | + |
| 41 | + public static ComparisonResult CssClassAttributeDifferenceEvaluator(Comparison comparison, ComparisonResult outcome) |
| 42 | + { |
| 43 | + if (comparison is null) throw new ArgumentNullException(nameof(comparison)); |
| 44 | + |
| 45 | + if (outcome == ComparisonResult.EQUAL) return outcome; |
| 46 | + if (comparison.Type != ComparisonType.ATTR_VALUE) return outcome; |
| 47 | + if (!comparison.TestDetails.Target.Name.Equals("class", StringComparison.OrdinalIgnoreCase)) return outcome; |
| 48 | + |
| 49 | + // BANG: Value should not be null on ControlDetails and TestDetails. |
| 50 | + var expected = comparison.ControlDetails.Value.ToString()!.Split(Space, StringSplitOptions.RemoveEmptyEntries); |
| 51 | + var actual = comparison.TestDetails.Value.ToString()!.Split(Space, StringSplitOptions.RemoveEmptyEntries); |
| 52 | + |
| 53 | + if (SetEqual(expected, actual)) return ComparisonResult.EQUAL; |
| 54 | + else return outcome; |
| 55 | + } |
| 56 | + |
| 57 | + private static bool SetEqual(string[] expected, string[] actual) |
| 58 | + { |
| 59 | + if (expected.Length != actual.Length) return false; |
| 60 | + return new HashSet<string>(expected).SetEquals(new HashSet<string>(actual)); |
| 61 | + } |
| 62 | + } |
| 63 | +} |
0 commit comments