// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; using LoggingWebSite; using Xunit.Sdk; namespace Microsoft.AspNet.Mvc.FunctionalTests { public static class LoggingAssert { /// /// Compares two trees and verifies if the scope nodes are equal /// /// /// /// public static bool ScopesEqual(ScopeNodeDto expected, ScopeNodeDto actual) { // To enable diagnosis, here a flat-list(pe-order traversal based) of // these trees is provided. if (!AreScopesEqual(expected, actual)) { var expectedScopes = new List(); var actualScopes = new List(); TraverseScopeTree(expected, expectedScopes); TraverseScopeTree(actual, actualScopes); throw new EqualException(expected: string.Join(", ", expectedScopes), actual: string.Join(", ", actualScopes)); } return true; } /// /// Compares two trees and verifies if the scope nodes are equal /// /// /// /// private static bool AreScopesEqual(ScopeNodeDto root1, ScopeNodeDto root2) { if (root1 == null && root2 == null) { return true; } if (root1 == null || root2 == null) { return false; } if (!string.Equals(root1.State?.ToString(), root2.State?.ToString(), StringComparison.OrdinalIgnoreCase) || root1.Children.Count != root2.Children.Count) { return false; } bool isChildScopeEqual = true; for (int i = 0; i < root1.Children.Count; i++) { isChildScopeEqual = AreScopesEqual(root1.Children[i], root2.Children[i]); if (!isChildScopeEqual) { break; } } return isChildScopeEqual; } /// /// Traverses the scope node sub-tree and collects the list scopes /// /// /// private static void TraverseScopeTree(ScopeNodeDto root, List scopes) { if (root == null) { return; } scopes.Add(root.State?.ToString()); foreach (var childScope in root.Children) { TraverseScopeTree(childScope, scopes); } } } }