<commit_before>﻿using System;
using System.Collections;
using System.Diagnostics;
using System.Linq;
using Xunit;
using System.Collections.Generic;
using System.Reflection;

namespace Octokit.Tests.Conventions
{
    public class ModelTests
    {
        [Theory]
        [MemberData("ModelTypes")]
        public void AllModelsHaveDebuggerDisplayAttribute(Type modelType)
        {
            var attribute = modelType.GetCustomAttribute<DebuggerDisplayAttribute>(inherit: false);
            if (attribute == null)
            {
                throw new MissingDebuggerDisplayAttributeException(modelType);
            }

            if (attribute.Value != "{DebuggerDisplay,nq}")
            {
                throw new InvalidDebuggerDisplayAttributeValueException(modelType, attribute.Value);
            }

            var property = modelType.GetProperty("DebuggerDisplay", BindingFlags.Instance | BindingFlags.NonPublic);
            if (property == null)
            {
                throw new MissingDebuggerDisplayPropertyException(modelType);
            }

            if (property.PropertyType != typeof(string))
            {
                throw new InvalidDebuggerDisplayReturnType(modelType, property.PropertyType);
            }
        }

        [Theory]
        [MemberData("ResponseModelTypes")]
        public void ResponseModelsHaveGetterOnlyProperties(Type modelType)
        {
            var mutableProperties = new List<PropertyInfo>();

            foreach (var property in modelType.GetProperties())
            {
                var setter = property.GetSetMethod(nonPublic: true);

                if (setter == null || !setter.IsPublic)
                {
                    continue;
                }

                mutableProperties.Add(property);
            }

            if (mutableProperties.Any())
            {
                throw new MutableModelPropertiesException(modelType, mutableProperties);
            }
        }

        [Theory]
        [MemberData("ResponseModelTypes")]
        public void ResponseModelsHaveReadOnlyCollections(Type modelType)
        {
            var mutableCollectionProperties = new List<PropertyInfo>();

            foreach (var property in modelType.GetProperties())
            {
                var propertyType = property.PropertyType;

                if (typeof(IEnumerable).IsAssignableFrom(propertyType))
                {
                    // Let's skip arrays as well for now.
                    // There seems to be some special array handling in the Gist model.
                    if (propertyType == typeof(string) || propertyType.IsArray)
                    {
                        continue;
                    }

                    if (propertyType.IsReadOnlyCollection())
                    {
                        continue;
                    }

                    // Let's skip collections that only have a private Setter
                    if (property.SetMethod != null && property.SetMethod.IsPrivate)
                    {
                        continue;
                    }

                    mutableCollectionProperties.Add(property);
                }
            }

            if (mutableCollectionProperties.Any())
            {
                throw new MutableModelPropertiesException(modelType, mutableCollectionProperties);
            }
        }

        //TODO: This should (probably) be moved to the PaginationTests class that is being introduced in PR #760
        [Theory]
        [MemberData("GetClientInterfaces")]
        public void CheckPaginationGetAllMethodNames(Type clientInterface)
        {
            var methodsOrdered = clientInterface.GetMethodsOrdered();

            var methodsThatCanPaginate = methodsOrdered
                .Where(x => x.ReturnType.GetTypeInfo().TypeCategory == TypeCategory.ReadOnlyList)
                .Where(x => x.Name.StartsWith("Get"));<commit_msg>Revert "potential fix to convention test problems with private setter on IGenericList"<commit_after>﻿using System;
using System.Collections;
using System.Diagnostics;
using System.Linq;
using Xunit;
using System.Collections.Generic;
using System.Reflection;

namespace Octokit.Tests.Conventions
{
    public class ModelTests
    {
        [Theory]
        [MemberData("ModelTypes")]
        public void AllModelsHaveDebuggerDisplayAttribute(Type modelType)
        {
            var attribute = modelType.GetCustomAttribute<DebuggerDisplayAttribute>(inherit: false);
            if (attribute == null)
            {
                throw new MissingDebuggerDisplayAttributeException(modelType);
            }

            if (attribute.Value != "{DebuggerDisplay,nq}")
            {
                throw new InvalidDebuggerDisplayAttributeValueException(modelType, attribute.Value);
            }

            var property = modelType.GetProperty("DebuggerDisplay", BindingFlags.Instance | BindingFlags.NonPublic);
            if (property == null)
            {
                throw new MissingDebuggerDisplayPropertyException(modelType);
            }

            if (property.PropertyType != typeof(string))
            {
                throw new InvalidDebuggerDisplayReturnType(modelType, property.PropertyType);
            }
        }

        [Theory]
        [MemberData("ResponseModelTypes")]
        public void ResponseModelsHaveGetterOnlyProperties(Type modelType)
        {
            var mutableProperties = new List<PropertyInfo>();

            foreach (var property in modelType.GetProperties())
            {
                var setter = property.GetSetMethod(nonPublic: true);

                if (setter == null || !setter.IsPublic)
                {
                    continue;
                }

                mutableProperties.Add(property);
            }

            if (mutableProperties.Any())
            {
                throw new MutableModelPropertiesException(modelType, mutableProperties);
            }
        }

        [Theory]
        [MemberData("ResponseModelTypes")]
        public void ResponseModelsHaveReadOnlyCollections(Type modelType)
        {
            var mutableCollectionProperties = new List<PropertyInfo>();

            foreach (var property in modelType.GetProperties())
            {
                var propertyType = property.PropertyType;

                if (typeof(IEnumerable).IsAssignableFrom(propertyType))
                {
                    // Let's skip arrays as well for now.
                    // There seems to be some special array handling in the Gist model.
                    if (propertyType == typeof(string) || propertyType.IsArray)
                    {
                        continue;
                    }

                    if (propertyType.IsReadOnlyCollection())
                    {
                        continue;
                    }

                    mutableCollectionProperties.Add(property);
                }
            }

            if (mutableCollectionProperties.Any())
            {
                throw new MutableModelPropertiesException(modelType, mutableCollectionProperties);
            }
        }

        //TODO: This should (probably) be moved to the PaginationTests class that is being introduced in PR #760
        [Theory]
        [MemberData("GetClientInterfaces")]
        public void CheckPaginationGetAllMethodNames(Type clientInterface)
        {
            var methodsOrdered = clientInterface.GetMethodsOrdered();

            var methodsThatCanPaginate = methodsOrdered
                .Where(x => x.ReturnType.GetTypeInfo().TypeCategory == TypeCategory.ReadOnlyList)
                .Where(x => x.Name.StartsWith("Get"));
{'fraction_non_alphanumeric': 0.07613488975356679, 'fraction_numerical': 0.0007782101167315176, 'mean_word_length': 1.727626459143969, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, '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': '6330573', 'n_tokens_mistral': 1762, 'n_tokens_neox': 1687, 'n_words': 382}