diff --git a/Octokit.Tests.Conventions/DebuggerDisplayOnModels.cs b/Octokit.Tests.Conventions/DebuggerDisplayOnModels.cs deleted file mode 100644 index c4635c99..00000000 --- a/Octokit.Tests.Conventions/DebuggerDisplayOnModels.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Diagnostics; -using System.Linq; -using Octokit.Tests.Helpers; -using Xunit; -using System.Collections.Generic; - -namespace Octokit.Tests.Conventions -{ - public class DebuggerDisplayOnModels - { - [Theory] - [MemberData("ModelTypes")] - public void CheckModelsForDebuggerDisplayAttribute(Type modelType) - { - AssertEx.HasAttribute(modelType); - } - - public static IEnumerable ModelTypes - { - get - { - foreach (var exportedType in typeof(IEventsClient).Assembly.ExportedTypes) - { - if (!exportedType.IsClientInterface()) - { - continue; - } - - var methods = exportedType.GetMethods(); - - var parameterTypes = methods.SelectMany(method => method.GetParameters(), (method, parameter) => parameter.ParameterType); - - var returnTypes = methods.Select(method => method.ReturnType); - - var modelTypes = parameterTypes.Union(returnTypes).Where(type => type.IsModel()); - - foreach (var modelType in modelTypes.Distinct()) - { - yield return new object[] { modelType }; - } - } - } - } - } -} \ No newline at end of file diff --git a/Octokit.Tests.Conventions/ModelTests.cs b/Octokit.Tests.Conventions/ModelTests.cs new file mode 100644 index 00000000..6521fb33 --- /dev/null +++ b/Octokit.Tests.Conventions/ModelTests.cs @@ -0,0 +1,87 @@ +using System; +using System.Diagnostics; +using System.Linq; +using Octokit.Tests.Helpers; +using Xunit; +using System.Collections.Generic; + +namespace Octokit.Tests.Conventions +{ + public class ModelTests + { + [Theory] + [MemberData("ModelTypes")] + public void HasDebuggerDisplayAttribute(Type modelType) + { + AssertEx.HasAttribute(modelType); + } + + [Theory] + [MemberData("ResponseModelTypes")] + public void HasGetterOnlyProperties(Type modelType) + { + foreach (var property in modelType.GetProperties()) + { + var setter = property.GetSetMethod(nonPublic: true); + + Assert.True(setter == null || !setter.IsPublic); + } + } + + public static IEnumerable ModelTypes + { + get { return GetModelTypes(includeRequestModels: true).Select(type => new[] { type }); } + } + + public static IEnumerable ResponseModelTypes + { + get { return GetModelTypes(includeRequestModels: false).Select(type => new[] { type }); } + } + + private static IEnumerable GetModelTypes(bool includeRequestModels) + { + var allModelTypes = new HashSet(); + + var clientInterfaces = typeof(IEventsClient).Assembly.ExportedTypes + .Where(type => type.IsClientInterface()); + + foreach (var exportedType in clientInterfaces) + { + var methods = exportedType.GetMethods(); + + var modelTypes = methods.Select(method => UnwrapGenericArgument(method.ReturnType)); + + if (includeRequestModels) + { + var requestModels = methods.SelectMany(method => method.GetParameters(), + (method, parameter) => parameter.ParameterType); + + modelTypes = modelTypes.Union(requestModels); + } + + foreach (var modelType in modelTypes.Where(type => type.IsModel())) + { + allModelTypes.Add(modelType); + } + } + + return allModelTypes; + } + + private static Type UnwrapGenericArgument(Type returnType) + { + if (returnType.IsGenericType) + { + var argument = returnType.GetGenericArgument(); + if (argument.IsModel()) + { + return argument; + } + + return UnwrapGenericArgument(argument); + } + + return returnType; + } + } +} \ No newline at end of file diff --git a/Octokit.Tests.Conventions/Octokit.Tests.Conventions.csproj b/Octokit.Tests.Conventions/Octokit.Tests.Conventions.csproj index 3a9ca23a..796e9fa0 100644 --- a/Octokit.Tests.Conventions/Octokit.Tests.Conventions.csproj +++ b/Octokit.Tests.Conventions/Octokit.Tests.Conventions.csproj @@ -55,7 +55,7 @@ - +