<commit_before>﻿// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Collections;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using Xunit;

namespace System.Linq.Tests
{
    public class ConsistencyTests
    {
        [Fact]
        public static void MatchSequencePattern()
        {
            // If a change to Enumerable has required a change to the exception list in this test
            // make the same change at src/System.Linq.Queryable/tests/Queryable.cs.
            MethodInfo enumerableNotInQueryable = GetMissingExtensionMethod(
                typeof(Enumerable),
                typeof(Queryable),
                 new[] {
                     nameof(Enumerable.ToLookup),
                     nameof(Enumerable.ToDictionary),
                     nameof(Enumerable.ToArray),
                     nameof(Enumerable.AsEnumerable),
                     nameof(Enumerable.ToList),
                     "Fold",
                     "LeftJoin",
                     "ToHashSet"
                 }
                );

            Assert.True(enumerableNotInQueryable == null, string.Format("Enumerable method {0} not defined by Queryable", enumerableNotInQueryable));

            MethodInfo queryableNotInEnumerable = GetMissingExtensionMethod(
                typeof(Queryable),
                typeof(Enumerable),
                 new[] {
                     nameof(Queryable.AsQueryable)
                 }
                );

            Assert.True(queryableNotInEnumerable == null, string.Format("Queryable method {0} not defined by Enumerable", queryableNotInEnumerable));
        }

        private static MethodInfo GetMissingExtensionMethod(Type a, Type b, IEnumerable<string> excludedMethods)
        {
            var dex = new HashSet<string>(excludedMethods);

            var aMethods =
                a.GetMethods(BindingFlags.Static | BindingFlags.Public)
                .Where(m => m.CustomAttributes.Any(c => c.AttributeType == typeof(ExtensionAttribute)))
                .ToLookup(m => m.Name);

            MethodComparer mc = new MethodComparer();
            var bMethods = b.GetMethods(BindingFlags.Static | BindingFlags.Public)
                .Where(m => m.CustomAttributes.Any(c => c.AttributeType == typeof(ExtensionAttribute)))
                .ToLookup(m => m, mc);

            foreach (var group in aMethods.Where(g => !dex.Contains(g.Key)))
            {
                foreach (MethodInfo m in group)
                {
                    if (!bMethods.Contains(m))
                        return m;
                }<commit_msg>Fixed netfx System.Linq.Tests fails (#28295)<commit_after>﻿// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Collections;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using Xunit;

namespace System.Linq.Tests
{
    public class ConsistencyTests
    {
        [Fact]
        public static void MatchSequencePattern()
        {
            MethodInfo enumerableNotInQueryable = GetMissingExtensionMethod(typeof(Enumerable), typeof(Queryable), GetExcludedMethods());

            Assert.True(enumerableNotInQueryable == null, string.Format("Enumerable method {0} not defined by Queryable", enumerableNotInQueryable));

            MethodInfo queryableNotInEnumerable = GetMissingExtensionMethod(
                typeof(Queryable),
                typeof(Enumerable),
                 new[] {
                     nameof(Queryable.AsQueryable)
                 }
                );

            Assert.True(queryableNotInEnumerable == null, string.Format("Queryable method {0} not defined by Enumerable", queryableNotInEnumerable));
        }

        // If a change to Enumerable has required a change to the exception list in this test
        // make the same change at src/System.Linq.Queryable/tests/Queryable.cs.
        private static IEnumerable<string> GetExcludedMethods()
        {
            IEnumerable<string> result = new[]
            {
                nameof(Enumerable.ToLookup),
                nameof(Enumerable.ToDictionary),
                nameof(Enumerable.ToArray),
                nameof(Enumerable.AsEnumerable),
                nameof(Enumerable.ToList),
                "Fold",
                "LeftJoin",
                "ToHashSet"
            };

            if (PlatformDetection.IsFullFramework)
            {
                result = result.Concat(new[]
                {
                    nameof(Enumerable.Append),
                    nameof(Enumerable.Prepend)
                });
            }

            return result;
        }

        private static MethodInfo GetMissingExtensionMethod(Type a, Type b, IEnumerable<string> excludedMethods)
        {
            var dex = new HashSet<string>(excludedMethods);

            var aMethods =
                a.GetMethods(BindingFlags.Static | BindingFlags.Public)
                .Where(m => m.CustomAttributes.Any(c => c.AttributeType == typeof(ExtensionAttribute)))
                .ToLookup(m => m.Name);

            MethodComparer mc = new MethodComparer();
            var bMethods = b.GetMethods(BindingFlags.Static | BindingFlags.Public)
                .Where(m => m.CustomAttributes.Any(c => c.AttributeType == typeof(ExtensionAttribute)))
                .ToLookup(m => m, mc);

            foreach (var group in aMethods.Where(g => !dex.Contains(g.Key)))
            {
                foreach (MethodInfo m in group)
                {
                    if (!bMethods.Contains(m))
                        return m;
                }
{'fraction_non_alphanumeric': 0.08626994680851063, 'fraction_numerical': 0.0014960106382978723, 'mean_word_length': 1.8503079109426812, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6333156', 'n_tokens_mistral': 1482, 'n_tokens_neox': 1401, 'n_words': 362}