Skip to content

Commit b770efa

Browse files
Restore static analysis test
Restore the static analysis test, as it works correctly now that the test project has a reference to JetBrains.Annotations which was added by ddd36cd.
1 parent b77b068 commit b770efa

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
3+
* See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
4+
* for more information concerning the license and the contributors participating to this project.
5+
*/
6+
7+
using System;
8+
using System.Collections.Generic;
9+
using System.Linq;
10+
using System.Reflection;
11+
using System.Runtime.Loader;
12+
using Shouldly;
13+
14+
namespace AspNet.Security.OAuth
15+
{
16+
public static class StaticAnalysisTests
17+
{
18+
#if JETBRAINS_ANNOTATIONS
19+
[Xunit.Fact]
20+
#endif
21+
public static void Publicly_Visible_Parameters_Have_Null_Annotations()
22+
{
23+
// Arrange
24+
var assemblyNames = GetProviderAssemblyNames();
25+
var types = GetPublicTypes(assemblyNames);
26+
27+
int testedMethods = 0;
28+
29+
// Act
30+
foreach (var type in types)
31+
{
32+
var methods = GetPublicOrProtectedConstructorsOrMethods(type);
33+
34+
foreach (var method in methods)
35+
{
36+
var parameters = method.GetParameters();
37+
38+
foreach (var parameter in parameters)
39+
{
40+
bool hasNullabilityAnnotation = parameter
41+
.GetCustomAttributes()
42+
.Any((p) => p.GetType().FullName == "JetBrains.Annotations.CanBeNullAttribute" ||
43+
p.GetType().FullName == "JetBrains.Annotations.NotNullAttribute");
44+
45+
// Assert
46+
hasNullabilityAnnotation.ShouldBeTrue(
47+
$"The {parameter.Name} parameter of {type.Name}.{method.Name} does not have a [NotNull] or [CanBeNull] annotation.");
48+
49+
testedMethods++;
50+
}
51+
}
52+
}
53+
54+
testedMethods.ShouldBeGreaterThan(0);
55+
}
56+
57+
private static IList<AssemblyName> GetProviderAssemblyNames()
58+
{
59+
var thisType = typeof(StaticAnalysisTests);
60+
61+
var assemblies = thisType.Assembly
62+
.GetReferencedAssemblies()
63+
.Where((p) => p.FullName.StartsWith(thisType.Namespace + ".", StringComparison.Ordinal))
64+
.ToArray();
65+
66+
assemblies.ShouldNotBeEmpty();
67+
68+
return assemblies;
69+
}
70+
71+
private static IList<Type> GetPublicTypes(IEnumerable<AssemblyName> assemblyNames)
72+
{
73+
var types = assemblyNames
74+
.Select((p) => AssemblyLoadContext.Default.LoadFromAssemblyName(p))
75+
.SelectMany((p) => p.GetTypes())
76+
.Where((p) => p.IsPublic || p.IsNestedPublic)
77+
.ToArray();
78+
79+
types.ShouldNotBeEmpty();
80+
81+
return types;
82+
}
83+
84+
private static IList<MethodBase> GetPublicOrProtectedConstructorsOrMethods(Type type)
85+
{
86+
var constructors = type
87+
.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic)
88+
.Select((p) => (MethodBase)p)
89+
.ToArray();
90+
91+
var methods = type
92+
.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)
93+
.ToArray();
94+
95+
return methods
96+
.Concat(constructors)
97+
.Where((p) => p.IsPublic || p.IsFamily) // public or protected
98+
.Where((p) => !p.IsAbstract)
99+
.Where((p) => !p.IsSpecialName) // No property get/set or event add/remove methods
100+
.ToArray();
101+
}
102+
}
103+
}

0 commit comments

Comments
 (0)