Skip to content

Commit 98abfd4

Browse files
committed
AUS-1007: Give the obsolete members diagnostic ids
1 parent 86988e1 commit 98abfd4

15 files changed

Lines changed: 178 additions & 27 deletions

‎AustinHarris.JsonRpcTestN/AsyncInvocationTests.cs‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,9 @@ public async Task CompatibilityRegistrationSurfaces_SupportAsyncMethods(int surf
140140
var method = new Func<Task<int>>(() => Task.FromResult(7));
141141
var handler = Handler.GetSessionHandler(_session);
142142
if (surface == 0) handler.MetaData.Services["run"] = new SMDService("POST", "JSON-RPC-2.0", types, new Dictionary<string, object>(), method);
143-
#pragma warning disable CS0618
143+
#pragma warning disable CS0618, JSONRPC0002
144144
else if (surface == 1) handler.RegisterFuction("run", types, null, method);
145-
#pragma warning restore CS0618
145+
#pragma warning restore CS0618, JSONRPC0002
146146
else _ = new AutoAsyncService(_session);
147147
Assert.AreEqual(7, (int)JObject.Parse(await Run(Request("run")))["result"]);
148148
Assert.AreEqual(typeof(int), handler.MetaData.Services["run"].Method.ResultType);
@@ -180,9 +180,9 @@ public void AsyncVoid_IsRejectedOnEverySurface(int surface)
180180
3 => () => Bind("invalid", invalid),
181181
4 => () => new InvalidAutoService(_session),
182182
5 => () => new SMDService("POST", "JSON-RPC-2.0", types, new Dictionary<string, object>(), invalid),
183-
#pragma warning disable CS0618
183+
#pragma warning disable CS0618, JSONRPC0002
184184
_ => () => Handler.GetSessionHandler(_session).RegisterFuction("invalid", types, null, invalid)
185-
#pragma warning restore CS0618
185+
#pragma warning restore CS0618, JSONRPC0002
186186
};
187187
StringAssert.Contains("async void", Assert.Throws<NotSupportedException>(registration).Message);
188188
}

‎AustinHarris.JsonRpcTestN/DelegateBindingTests.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,9 @@ public void Names_MustBeFree_AndUnbindFreesThem()
128128
Assert.AreEqual("{\"jsonrpc\":\"2.0\",\"result\":2,\"id\":1}", Run("{\"method\":\"m\",\"id\":1}"));
129129

130130
// the legacy surface keeps replacing silently
131-
#pragma warning disable CS0618
131+
#pragma warning disable CS0618, JSONRPC0002
132132
Handler.GetSessionHandler(Session).RegisterFuction("m", new Dictionary<string, Type> { ["returns"] = typeof(int) }, null, new Func<int>(() => 3));
133-
#pragma warning restore CS0618
133+
#pragma warning restore CS0618, JSONRPC0002
134134
Assert.AreEqual("{\"jsonrpc\":\"2.0\",\"result\":3,\"id\":1}", Run("{\"method\":\"m\",\"id\":1}"));
135135
}
136136

‎AustinHarris.JsonRpcTestN/DispatchHardeningTests.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,9 @@ public void BindServices()
154154
public void DestroySessions()
155155
{
156156
Handler.DestroySession(Session);
157-
#pragma warning disable CS0618
157+
#pragma warning disable CS0618, JSONRPC0003
158158
Handler.DefaultHandler.UnRegisterFunction("dh.whichSession");
159-
#pragma warning restore CS0618
159+
#pragma warning restore CS0618, JSONRPC0003
160160
}
161161

162162
private static string Run(string json, object context = null, JsonRpcSerializer serializer = null, string session = Session)

‎AustinHarris.JsonRpcTestN/NewtonsoftTests.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,9 @@ public void Settings_PerSession_OverridesGlobal()
9393
try
9494
{
9595
var h = Handler.GetSessionHandler(sessionId);
96-
#pragma warning disable CS0618
96+
#pragma warning disable CS0618, JSONRPC0002
9797
h.RegisterFuction("echo", new System.Collections.Generic.Dictionary<string, Type> { { "s", typeof(string) }, { "returns", typeof(string) } }, null, new Func<string, string>(s => s));
98-
#pragma warning restore CS0618
98+
#pragma warning restore CS0618, JSONRPC0002
9999
h.Serializer = new NewtonsoftJsonRpcSerializer(new JsonSerializerSettings { Converters = { new ShoutingStringConverter() } });
100100
// four arguments on purpose: ProcessSync(sessionId, json, null) binds to the (jsonRpc, context, serializer) overload
101101
var result = JsonRpcProcessor.ProcessSync(sessionId, "{\"method\":\"echo\",\"params\":[\"abc\"],\"id\":1}", null, null);
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
using System;
2+
using System.Linq;
3+
using System.Reflection;
4+
using System.Text.RegularExpressions;
5+
using AustinHarris.JsonRpc;
6+
using NUnit.Framework;
7+
8+
namespace AustinHarris.JsonRpcTestN
9+
{
10+
/// <summary>Verifies the stable diagnostics on obsolete public APIs.</summary>
11+
[TestFixture]
12+
public class ObsoletionTests
13+
{
14+
private const string UrlFormat = "https://astn.github.io/JSON-RPC.NET/obsoletions.html#{0}";
15+
16+
/// <summary>Checks the session pre-process alias diagnostic.</summary>
17+
[Test]
18+
public void SetBeforeProcessHandler_HasDiagnosticAndMigrationMessage()
19+
{
20+
AssertObsolete(typeof(Config), "SetBeforeProcessHandler", "JSONRPC0001",
21+
"Use SetPreProcessHandler(sessionId, handler).");
22+
}
23+
24+
/// <summary>Checks the legacy registration diagnostic.</summary>
25+
[Test]
26+
public void RegisterFuction_HasDiagnosticAndMigrationMessage()
27+
{
28+
AssertObsolete(typeof(Handler), "RegisterFuction", "JSONRPC0002",
29+
"Use ServiceBinder.BindMethod; unlike RegisterFuction it throws when the name is already registered instead of replacing it.");
30+
}
31+
32+
/// <summary>Checks the legacy unregistration diagnostic.</summary>
33+
[Test]
34+
public void UnRegisterFunction_HasDiagnosticAndMigrationMessage()
35+
{
36+
AssertObsolete(typeof(Handler), "UnRegisterFunction", "JSONRPC0003",
37+
"Use ServiceBinder.UnbindMethod.");
38+
}
39+
40+
/// <summary>Checks that core obsoletion IDs are reserved, unique and discoverable.</summary>
41+
[Test]
42+
public void DiagnosticIds_AreUniqueAndInTheObsoletionRange()
43+
{
44+
var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly;
45+
var ids = typeof(Config).Assembly.GetTypes()
46+
.SelectMany(type => new MemberInfo[] { type }.Concat(type.GetMembers(flags)))
47+
.Select(member => member.GetCustomAttribute<ObsoleteAttribute>())
48+
.Where(attribute => attribute != null && attribute.DiagnosticId != null)
49+
.Select(attribute => attribute.DiagnosticId)
50+
.ToArray();
51+
52+
Assert.GreaterOrEqual(ids.Length, 3, "The scan must find the three current obsoletions.");
53+
CollectionAssert.Contains(ids, "JSONRPC0001");
54+
CollectionAssert.Contains(ids, "JSONRPC0002");
55+
CollectionAssert.Contains(ids, "JSONRPC0003");
56+
Assert.AreEqual(ids.Length, ids.Distinct(StringComparer.Ordinal).Count(), "Diagnostic IDs must be unique.");
57+
foreach (string id in ids)
58+
Assert.IsTrue(Regex.IsMatch(id, @"^JSONRPC0\d{3}$"), $"Unexpected diagnostic ID: {id}");
59+
}
60+
61+
private static void AssertObsolete(Type declaringType, string memberName, string diagnosticId, string message)
62+
{
63+
var method = declaringType.GetMethod(memberName);
64+
Assert.NotNull(method);
65+
var attribute = method.GetCustomAttribute<ObsoleteAttribute>();
66+
Assert.NotNull(attribute);
67+
Assert.IsFalse(attribute.IsError);
68+
#if NET5_0_OR_GREATER
69+
Assert.AreEqual(diagnosticId, attribute.DiagnosticId);
70+
Assert.AreEqual(UrlFormat, attribute.UrlFormat);
71+
#endif
72+
Assert.AreEqual(message, attribute.Message);
73+
}
74+
}
75+
}

‎AustinHarris.JsonRpcTestN/ReservedNameTests.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,15 +137,15 @@ public void AttributeBinder_RefusesReservedAliases_AcceptsTheRest()
137137
public void RegisterFuction_RefusesReserved_AcceptsTheRest()
138138
{
139139
var handler = Handler.GetSessionHandler(Session);
140-
#pragma warning disable CS0618
140+
#pragma warning disable CS0618, JSONRPC0002
141141
foreach (var name in Reserved)
142142
AssertReserved(name, () => handler.RegisterFuction(name, new Dictionary<string, Type> { ["returns"] = typeof(int) }, null, new Func<int>(() => 1)));
143143
foreach (var name in Allowed)
144144
{
145145
handler.RegisterFuction(name, new Dictionary<string, Type> { ["returns"] = typeof(int) }, null, new Func<int>(() => 1));
146146
AssertRegistered(name);
147147
}
148-
#pragma warning restore CS0618
148+
#pragma warning restore CS0618, JSONRPC0002
149149
}
150150

151151
[Test]

‎AustinHarris.JsonRpcTestN/SessionAndConfigTests.cs‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,9 @@ public void Config_SetBeforeProcessHandler_IsAnAliasOfSetPreProcessHandler()
203203
int pre = 0;
204204
try
205205
{
206-
#pragma warning disable CS0618
206+
#pragma warning disable CS0618, JSONRPC0001
207207
Config.SetBeforeProcessHandler(Session, (request, context) => { pre++; return null; });
208-
#pragma warning restore CS0618
208+
#pragma warning restore CS0618, JSONRPC0001
209209
JsonRpcProcessor.ProcessSync(Session, "{\"jsonrpc\":\"2.0\",\"method\":\"sc.ping\",\"id\":1}", null);
210210
Assert.AreEqual(1, pre);
211211
Config.SetPreProcessHandler(Session, null);
@@ -250,10 +250,10 @@ public void JsonRpcService_AutoBindFalse_BindsNowhere_UntilBoundExplicitly()
250250
}
251251
finally
252252
{
253-
#pragma warning disable CS0618
253+
#pragma warning disable CS0618, JSONRPC0003
254254
Handler.DefaultHandler.UnRegisterFunction("sc.bound");
255255
Handler.GetSessionHandler(Session).UnRegisterFunction("sc.unbound");
256-
#pragma warning restore CS0618
256+
#pragma warning restore CS0618, JSONRPC0003
257257
}
258258
}
259259
}

‎AustinHarris.JsonRpcTestN/Test.cs‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,9 @@ public void TestCanCreateAndRemoveSession()
9595
Tuple.Create ("sooper", typeof(string)),
9696
Tuple.Create ("returns", typeof(string))
9797
}.ToDictionary(x => x.Item1, x => x.Item2);
98-
#pragma warning disable CS0618
98+
#pragma warning disable CS0618, JSONRPC0002
9999
h.RegisterFuction("workie", metadata, new System.Collections.Generic.Dictionary<string, object>(),new Func<string, string>(x => "workie ... " + x));
100-
#pragma warning restore CS0618
100+
#pragma warning restore CS0618, JSONRPC0002
101101

102102
string request = @"{""method"":""workie"",""params"":{""sooper"":""good""},""id"":1}";
103103
string expectedResult = "{\"jsonrpc\":\"2.0\",\"result\":\"workie ... good\",\"id\":1}";
@@ -1614,9 +1614,9 @@ public void TestPreProcessOnSession()
16141614
Tuple.Create ("sooper", typeof(string)),
16151615
Tuple.Create ("returns", typeof(string))
16161616
}.ToDictionary(x => x.Item1, x => x.Item2);
1617-
#pragma warning disable CS0618
1617+
#pragma warning disable CS0618, JSONRPC0002
16181618
h.RegisterFuction("workie", metadata, new System.Collections.Generic.Dictionary<string, object>(),new Func<string, string>(x => "workie ... " + x));
1619-
#pragma warning restore CS0618
1619+
#pragma warning restore CS0618, JSONRPC0002
16201620

16211621
string request = @"{""method"":""workie"",""params"":{""sooper"":""good""},""id"":1}";
16221622
string expectedResult = "{\"jsonrpc\":\"2.0\",\"result\":\"workie ... good\",\"id\":1}";
@@ -1856,9 +1856,9 @@ public void TestPostProcessOnSession()
18561856
Tuple.Create ("sooper", typeof(string)),
18571857
Tuple.Create ("returns", typeof(string))
18581858
}.ToDictionary(x => x.Item1, x => x.Item2);
1859-
#pragma warning disable CS0618
1859+
#pragma warning disable CS0618, JSONRPC0002
18601860
h.RegisterFuction("workie", metadata, new System.Collections.Generic.Dictionary<string, object>(), new Func<string, string>(x => "workie ... " + x));
1861-
#pragma warning restore CS0618
1861+
#pragma warning restore CS0618, JSONRPC0002
18621862

18631863
string request = @"{""method"":""workie"",""params"":{""sooper"":""good""},""id"":1}";
18641864
string expectedResult = "{\"jsonrpc\":\"2.0\",\"result\":\"workie ... good\",\"id\":1}";

‎CHANGELOG.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ behaviour: a breaking change to either means a new major version.
4848
- Dates and non-finite numbers are written the same way by every serializer (fraction only when non-zero, `Z`/offset/nothing by `Kind`; `NaN` and the infinities as quoted strings).
4949
- Clarified that the WebAssembly sample is not a Native AOT or full-trimming compatibility guarantee.
5050

51+
### Deprecated
52+
53+
- `Config.SetBeforeProcessHandler` (`JSONRPC0001`), `Handler.RegisterFuction` (`JSONRPC0002`) and `Handler.UnRegisterFunction` (`JSONRPC0003`) are obsolete at warning level with a diagnostic id linking to [docs/obsoletions.md](docs/obsoletions.md); they stay through 2.x and are removed in 3.0.
54+
5155
### Removed
5256

5357
- `InProcessClient` (obsolete since 1.x); call `JsonRpcProcessor.Process` directly.

‎Json-Rpc/Config.cs‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,11 @@ public static void SetPostProcessHandler(string sessionId, PostProcessHandler ha
141141
}
142142

143143
/// <summary>The former name of <see cref="SetPreProcessHandler(string, PreProcessHandler)"/>.</summary>
144-
[Obsolete("Use SetPreProcessHandler(sessionId, handler).")]
144+
#if NET5_0_OR_GREATER
145+
[Obsolete(Obsoletions.SetBeforeProcessHandlerMessage, DiagnosticId = Obsoletions.SetBeforeProcessHandlerDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
146+
#else
147+
[Obsolete(Obsoletions.SetBeforeProcessHandlerDiagId + ": " + Obsoletions.SetBeforeProcessHandlerMessage)]
148+
#endif
145149
public static void SetBeforeProcessHandler(string sessionId, PreProcessHandler handler)
146150
{
147151
SetPreProcessHandler(sessionId, handler);

0 commit comments

Comments
 (0)