Skip to content

Commit 674f63f

Browse files
committed
Use Key factory instead of constructor
1 parent e811af6 commit 674f63f

File tree

2 files changed

+178
-105
lines changed
  • src/bunit.web/EventDispatchExtensions
  • tests/bunit.web.tests/EventDispatchExtensions

2 files changed

+178
-105
lines changed

src/bunit.web/EventDispatchExtensions/Key.cs

Lines changed: 103 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Diagnostics.CodeAnalysis;
4+
using System.Linq;
35
using Microsoft.AspNetCore.Components.Web;
46

57
namespace Bunit
@@ -9,42 +11,71 @@ namespace Bunit
911
/// </summary>
1012
public sealed class Key : IEquatable<Key>
1113
{
12-
/// <summary>
13-
/// Creates a new instance of the <see cref="Key"/> class.
14-
/// </summary>
15-
/// <param name="value">The key value.</param>
16-
public Key(string value)
17-
: this(value, value)
18-
{
19-
}
14+
private static readonly Dictionary<(string value, string code), Key> PredefinedKeys;
2015

21-
/// <summary>
22-
/// Creates a new instance of the <see cref="Key"/> class.
23-
/// </summary>
24-
/// <param name="value">The key value.</param>
25-
/// <param name="code">The key code of physical key.</param>
26-
public Key(string value, string code)
16+
[SuppressMessage("Microsoft.Performance", "CA1810:Initialize reference type static fields inline", Justification = "Properties are initialized after fields")]
17+
static Key()
2718
{
28-
if (string.IsNullOrEmpty(value))
29-
{
30-
throw new ArgumentNullException(nameof(value));
31-
}
32-
33-
if (string.IsNullOrEmpty(code))
19+
PredefinedKeys = new[]
3420
{
35-
throw new ArgumentNullException(nameof(code));
36-
}
21+
Key.Backspace,
22+
Key.Tab,
23+
Key.Enter,
24+
Key.Pause,
25+
Key.Escape,
26+
Key.Space,
27+
Key.PageUp,
28+
Key.PageDown,
29+
Key.End,
30+
Key.Home,
31+
Key.Left,
32+
Key.Up,
33+
Key.Right,
34+
Key.Down,
35+
Key.Insert,
36+
Key.Delete,
37+
Key.Equal,
38+
Key.NumberPad0,
39+
Key.NumberPad1,
40+
Key.NumberPad2,
41+
Key.NumberPad3,
42+
Key.NumberPad4,
43+
Key.NumberPad5,
44+
Key.NumberPad6,
45+
Key.NumberPad7,
46+
Key.NumberPad8,
47+
Key.NumberPad9,
48+
Key.Multiply,
49+
Key.Add,
50+
Key.Subtract,
51+
Key.NumberPadDecimal,
52+
Key.Divide,
53+
Key.F1,
54+
Key.F2,
55+
Key.F3,
56+
Key.F4,
57+
Key.F5,
58+
Key.F6,
59+
Key.F7,
60+
Key.F8,
61+
Key.F9,
62+
Key.F10,
63+
Key.F11,
64+
Key.F12,
65+
Key.Control,
66+
Key.Shift,
67+
Key.Alt,
68+
Key.Command
69+
}.ToDictionary(k => (k.Value, k.Code));
70+
}
3771

38-
Value = value;
39-
Code = code;
72+
private Key(string value)
73+
: this(value, value)
74+
{
4075
}
4176

42-
/// <summary>
43-
/// Creates a new instance of the <see cref="Key"/> class.
44-
/// </summary>
45-
/// <param name="value">The key value.</param>
46-
public Key(char value)
47-
: this(value.ToString())
77+
private Key(string value, string code)
78+
: this(value, code, false, false, false, false)
4879
{
4980
}
5081

@@ -332,10 +363,43 @@ private Key(string value, string code, bool controlKey, bool shiftKey, bool altK
332363
public static Key Command { get; } = new Key("Meta", "MetaLeft", false, false, false, true);
333364

334365
/// <summary>
335-
/// Creates a new instance of the <see cref="Key"/> class from specified character.
366+
/// Gets <see cref="Key"/> object with specified value and code.
367+
/// </summary>
368+
/// <param name="value">The key value.</param>
369+
/// <param name="code">The key code of physical key.</param>
370+
public static Key Get(string value, string code)
371+
{
372+
if (string.IsNullOrEmpty(value))
373+
{
374+
throw new ArgumentNullException(nameof(value));
375+
}
376+
377+
if (string.IsNullOrEmpty(code))
378+
{
379+
throw new ArgumentNullException(nameof(code));
380+
}
381+
382+
if (PredefinedKeys.TryGetValue((value, code), out var key))
383+
{
384+
return key;
385+
}
386+
else
387+
{
388+
return new Key(value, code);
389+
}
390+
}
391+
392+
/// <summary>
393+
/// Gets <see cref="Key"/> object with specified value.
394+
/// </summary>
395+
/// <param name="value">The key value.</param>
396+
public static Key Get(string value) => Get(value, value);
397+
398+
/// <summary>
399+
/// Gets <see cref="Key"/> object from specified character.
336400
/// </summary>
337401
/// <param name="value">The key value.</param>
338-
public static Key FromChar(char value) => new Key(value);
402+
public static Key Get(char value) => Get(value.ToString());
339403

340404
/// <summary>
341405
/// Gets the value indicating whether the current object is equal to another object of the same type.
@@ -492,7 +556,7 @@ static bool IsSuitableForCombination(Key key)
492556
/// <returns>A new key with combination of Control, Shift, Alt, and Command keys.</returns>
493557
[return: NotNullIfNotNull("x")]
494558
[return: NotNullIfNotNull("y")]
495-
[SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Alternative method is named Combine")]
559+
[SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Alternative method is named " + nameof(Combine))]
496560
public static Key operator +(Key x, Key? y)
497561
{
498562
if (!(x is null))
@@ -507,7 +571,8 @@ static bool IsSuitableForCombination(Key key)
507571
{
508572
// In future 'x' should be supported as nullable.
509573
// However, NotNullIfNotNull does not work correctly with operators.
510-
// Therfore workaround is to make 'x' non-nullable.
574+
// Therfore workaround is to make 'x' non-nullable.
575+
// See: https://github.com/dotnet/roslyn/issues/48489
511576
return null!;
512577
}
513578
}
@@ -517,7 +582,8 @@ static bool IsSuitableForCombination(Key key)
517582
/// </summary>
518583
/// <param name="key">The character to convert to Key instance.</param>
519584
/// <returns>The Key instance with character value.</returns>
520-
public static implicit operator Key(char key) => new Key(key);
585+
[SuppressMessage("Usage", "CA2225:Operator overloads have named alternates", Justification = "Alternative method is named " + nameof(Get))]
586+
public static implicit operator Key(char key) => Key.Get(key);
521587

522588
/// <summary>
523589
/// Gets a new <see cref="Key" /> instance with value of character.
@@ -532,7 +598,8 @@ public static implicit operator KeyboardEventArgs(Key key)
532598
{
533599
// In future the operator should support null as input.
534600
// However, NotNullIfNotNull does not work correctly with operators.
535-
// Therfore workaround is to make input non-nullable.
601+
// Therfore workaround is to make input non-nullable.
602+
// See: https://github.com/dotnet/roslyn/issues/39802
536603
return null!;
537604
}
538605

0 commit comments

Comments
 (0)