Skip to content

Commit

Permalink
Merge pull request OpenTabletDriver#3027 from gonX/tests-tabletconfig…
Browse files Browse the repository at this point in the history
…-schema

Tests: Verify tablet configurations with JSON Schema
  • Loading branch information
X9VoiD authored Nov 25, 2023
2 parents 58c9177 + 258f191 commit 5218f43
Show file tree
Hide file tree
Showing 16 changed files with 90 additions and 27 deletions.
3 changes: 2 additions & 1 deletion OpenTabletDriver.Analyzers/OpenTabletDriver.Analyzers.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.4.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.4.0" />
<PackageReference Include="JetBrains.Annotations" Version="2021.3.0" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
</ItemGroup>

<ItemGroup>
Expand All @@ -25,7 +26,7 @@
</ItemGroup>

<ItemGroup Label="Generator Dependencies">
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" GeneratePathProperty="true" PrivateAssets="all" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" GeneratePathProperty="true" PrivateAssets="all" />
</ItemGroup>

<Target Name="GetDependencyTargetPaths">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
},
"Pen": {
"MaxPressure": 1023,
"Buttons": {
"ButtonCount": 2
}
"ButtonCount": 2
},
"AuxiliaryButtons": null,
"MouseButtons": null,
Expand Down Expand Up @@ -40,7 +38,7 @@
"InitializationStrings": []
}
],
"AuxilaryDeviceIdentifiers": [],
"AuxiliaryDeviceIdentifiers": [],
"Attributes": {
"libinputoverride": "1"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
},
"Pen": {
"MaxPressure": 511,
"Buttons": {
"ButtonCount": 1
}
"ButtonCount": 1
},
"AuxiliaryButtons": {
"ButtonCount": 2
Expand All @@ -36,4 +34,4 @@
],
"AuxiliaryDeviceIdentifiers": [],
"Attributes": {}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
},
"Pen": {
"MaxPressure": 2048,
"Buttons": {
"ButtonCount": 2
}
"ButtonCount": 2
},
"AuxiliaryButtons": {
"ButtonCount": 8
Expand All @@ -34,5 +32,6 @@
"InitializationStrings": []
}
],
"AuxiliaryDeviceIdentifiers": [],
"Attributes": {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
},
"Pen": {
"MaxPressure": 2046,
"Buttons": {
"ButtonCount": 2
}
"ButtonCount": 2
},
"AuxiliaryButtons": {
"ButtonCount": 8
Expand All @@ -34,5 +32,6 @@
"InitializationStrings": []
}
],
"AuxiliaryDeviceIdentifiers": [],
"Attributes": {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
},
"Pen": {
"MaxPressure": 8191,
"Buttons": {
"ButtonCount": 2
}
"ButtonCount": 2
},
"AuxiliaryButtons": {
"ButtonCount": 10
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
</PropertyGroup>

<ItemGroup Label="NuGet Packages">
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

<ItemGroup Label="Project References">
Expand Down
58 changes: 51 additions & 7 deletions OpenTabletDriver.Tests/ConfigurationTest.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Schema;
using Newtonsoft.Json.Schema.Generation;
using OpenTabletDriver.Components;
using OpenTabletDriver.Tablet;
using Xunit;
Expand All @@ -28,9 +32,9 @@ public void Configurations_Have_ExistentParsers()
var configurationProvider = serviceProvider.GetRequiredService<IDeviceConfigurationProvider>();

var parsers = from configuration in configurationProvider.TabletConfigurations
from identifier in configuration.DigitizerIdentifiers.Concat(configuration.AuxiliaryDeviceIdentifiers)
orderby identifier.ReportParser
select identifier.ReportParser;
from identifier in configuration.DigitizerIdentifiers.Concat(configuration.AuxiliaryDeviceIdentifiers)
orderby identifier.ReportParser
select identifier.ReportParser;

var failed = false;

Expand Down Expand Up @@ -235,12 +239,12 @@ public void Configurations_DeviceIdentifier_IsNotConflicting()
.GetRequiredService<IDeviceConfigurationProvider>();

var digitizerIdentificationContexts = from config in configurationProvider.TabletConfigurations
from identifier in config.DigitizerIdentifiers.Select((d, i) => new { DeviceIdentifier = d, Index = i })
select new IdentificationContext(config, identifier.DeviceIdentifier, IdentifierType.Digitizer, identifier.Index);
from identifier in config.DigitizerIdentifiers.Select((d, i) => new { DeviceIdentifier = d, Index = i })
select new IdentificationContext(config, identifier.DeviceIdentifier, IdentifierType.Digitizer, identifier.Index);

var auxIdentificationContexts = from config in configurationProvider.TabletConfigurations
from identifier in config.AuxiliaryDeviceIdentifiers.Select((d, i) => new { DeviceIdentifier = d, Index = i })
select new IdentificationContext(config, identifier.DeviceIdentifier, IdentifierType.Auxiliary, identifier.Index);
from identifier in config.AuxiliaryDeviceIdentifiers.Select((d, i) => new { DeviceIdentifier = d, Index = i })
select new IdentificationContext(config, identifier.DeviceIdentifier, IdentifierType.Auxiliary, identifier.Index);

var identificationContexts = digitizerIdentificationContexts.Concat(auxIdentificationContexts);

Expand Down Expand Up @@ -270,6 +274,46 @@ static void AssertGroup(List<IdentificationContext> identificationContexts, Iden
}
}

private static readonly string ConfigurationProjectDir = Path.GetFullPath(Path.Join("../../../..", "OpenTabletDriver.Configurations"));
private static readonly string ConfigurationDir = Path.Join(ConfigurationProjectDir, "Configurations");
private static readonly IEnumerable<(string, string)> ConfigFiles = Directory.EnumerateFiles(ConfigurationDir, "*.json", SearchOption.AllDirectories)
.Select(f => (Path.GetRelativePath(ConfigurationDir, f), File.ReadAllText(f)));

[Fact]
public void Configurations_Verify_Configs_With_Schema()
{
var gen = new JSchemaGenerator();
var schema = gen.Generate(typeof(TabletConfiguration));
DisallowAdditionalItemsAndProperties(schema);

var failed = false;

foreach (var (tabletFilename, tabletConfigString) in ConfigFiles)
{
var tabletConfig = JObject.Parse(tabletConfigString);
if (tabletConfig.IsValid(schema, out IList<string> errors)) continue;

_testOutputHelper.WriteLine($"Tablet Configuration {tabletFilename} did not match schema:\r\n{string.Join("\r\n", errors)}\r\n");
failed = true;
}

Assert.False(failed);
}

private static void DisallowAdditionalItemsAndProperties(JSchema schema)
{
schema.AllowAdditionalItems = false;
schema.AllowAdditionalProperties = false;
schema.AllowUnevaluatedItems = false;
schema.AllowUnevaluatedProperties = false;

foreach (var child in schema.Properties)
{
if (child.Key == nameof(TabletConfiguration.Attributes)) continue;
DisallowAdditionalItemsAndProperties(child.Value);
}
}

private static void AssertInequal(IdentificationContext a, IdentificationContext b)
{
if (IsEqual(a.Identifier, b.Identifier))
Expand Down
1 change: 1 addition & 0 deletions OpenTabletDriver.Tests/OpenTabletDriver.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
<PackageReference Include="Moq" Version="4.16.1" />
<PackageReference Include="Newtonsoft.Json.Schema" Version="3.0.15" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
2 changes: 1 addition & 1 deletion OpenTabletDriver/OpenTabletDriver.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<ItemGroup Label="NuGet Packages">
<PackageReference Include="HidSharpCore" Version="1.2.1.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0-rc.1.21451.13" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

<ItemGroup Label="Project References">
Expand Down
2 changes: 2 additions & 0 deletions OpenTabletDriver/Tablet/ButtonSpecifications.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using JetBrains.Annotations;

namespace OpenTabletDriver.Tablet
Expand All @@ -13,6 +14,7 @@ public class ButtonSpecifications
/// The amount of buttons.
/// </summary>
[DisplayName("Buttons")]
[Required(ErrorMessage = $"{nameof(ButtonCount)} must be defined")]
public uint ButtonCount { set; get; }
}
}
6 changes: 6 additions & 0 deletions OpenTabletDriver/Tablet/DeviceIdentifier.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using JetBrains.Annotations;

namespace OpenTabletDriver.Tablet
Expand All @@ -14,12 +15,16 @@ public class DeviceIdentifier
/// The Vendor ID of the device.
/// </summary>
[DisplayName("Vendor ID")]
[Required(ErrorMessage = $"{nameof(VendorID)} identifier must be defined")]
[Range(0, 0xFFFF)]
public int VendorID { set; get; }

/// <summary>
/// The Product ID of the device.
/// </summary>
[DisplayName("Product ID")]
[Required(ErrorMessage = $"{nameof(ProductID)} identifier must be defined")]
[Range(0, 0xFFFF)]
public int ProductID { set; get; }

/// <summary>
Expand All @@ -38,6 +43,7 @@ public class DeviceIdentifier
/// The device report parser used by the detected device.
/// </summary>
[DisplayName("Report Parser")]
[RegularExpression(@"^([A-Za-z]+\w*)(\.[A-Za-z]+\w*)+$", ErrorMessage = $"{nameof(ReportParser)} for identifier must match regular expression")]
public string ReportParser { set; get; } = string.Empty;

/// <summary>
Expand Down
5 changes: 5 additions & 0 deletions OpenTabletDriver/Tablet/DigitizerSpecifications.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using JetBrains.Annotations;

namespace OpenTabletDriver.Tablet
Expand All @@ -12,22 +13,26 @@ public class DigitizerSpecifications
/// <summary>
/// The width of the digitizer in millimeters.
/// </summary>
[Required(ErrorMessage = $"Digitizer ${nameof(Width)} must be defined")]
public float Width { set; get; }

/// <summary>
/// The height of the digitizer in millimeters.
/// </summary>
[Required(ErrorMessage = $"Digitizer ${nameof(Height)} must be defined")]
public float Height { set; get; }

/// <summary>
/// The maximum X coordinate for the digitizer.
/// </summary>
[Required(ErrorMessage = $"Digitizer ${nameof(MaxX)} must be defined")]
[DisplayName("Max X")]
public float MaxX { set; get; }

/// <summary>
/// The maximum Y coordinate for the digitizer.
/// </summary>
[Required(ErrorMessage = $"Digitizer ${nameof(MaxY)} must be defined")]
[DisplayName("Max Y")]
public float MaxY { set; get; }
}
Expand Down
2 changes: 2 additions & 0 deletions OpenTabletDriver/Tablet/PenSpecifications.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using JetBrains.Annotations;

namespace OpenTabletDriver.Tablet
Expand All @@ -13,6 +14,7 @@ public class PenSpecifications : ButtonSpecifications
/// The maximum pressure that the pen supports.
/// </summary>
[DisplayName("Max Pressure")]
[Required(ErrorMessage = $"Pen {nameof(MaxPressure)} must be defined")]
public uint MaxPressure { set; get; }
}
}
7 changes: 7 additions & 0 deletions OpenTabletDriver/Tablet/TabletConfiguration.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using JetBrains.Annotations;

namespace OpenTabletDriver.Tablet
Expand All @@ -13,28 +14,34 @@ public class TabletConfiguration
/// <summary>
/// The tablet's name.
/// </summary>
[Required(ErrorMessage = $"Tablet {nameof(Name)} is required")]
public string Name { set; get; } = string.Empty;

/// <summary>
/// The tablet's specifications.
/// </summary>
[Required(ErrorMessage = $"Tablet {nameof(Specifications)} is required")]
public TabletSpecifications Specifications { set; get; } = new TabletSpecifications();

/// <summary>
/// The digitizer device identifier.
/// </summary>
[Required(ErrorMessage = $"Tablet {nameof(DigitizerIdentifiers)} are required")]
[DisplayName("Digitizer Identifiers")]
[MinLength(1, ErrorMessage = "Requires at least 1 identifier")]
public List<DeviceIdentifier> DigitizerIdentifiers { set; get; } = new List<DeviceIdentifier>();

/// <summary>
/// The auxiliary device identifier.
/// </summary>
[Required(ErrorMessage = $"Tablet {nameof(AuxiliaryDeviceIdentifiers)} must be present")]
[DisplayName("Auxiliary Identifiers")]
public List<DeviceIdentifier> AuxiliaryDeviceIdentifiers { set; get; } = new List<DeviceIdentifier>();

/// <summary>
/// Other information about the tablet that can be used in tools or other applications.
/// </summary>
[Required(ErrorMessage = $"Tablet {nameof(Attributes)} must be present")]
public Dictionary<string, string> Attributes { set; get; } = new Dictionary<string, string>();
}
}
3 changes: 3 additions & 0 deletions OpenTabletDriver/Tablet/TabletSpecifications.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using JetBrains.Annotations;

namespace OpenTabletDriver.Tablet
Expand All @@ -12,11 +13,13 @@ public class TabletSpecifications
/// <summary>
/// Specifications for the tablet digitizer.
/// </summary>
[Required(ErrorMessage = $"{nameof(Digitizer)} specifications must be defined")]
public DigitizerSpecifications? Digitizer { set; get; }

/// <summary>
/// Specifications for the tablet's pen.
/// </summary>
[Required(ErrorMessage = $"{nameof(Pen)} specifications must be defined")]
public PenSpecifications? Pen { set; get; }

/// <summary>
Expand Down

0 comments on commit 5218f43

Please sign in to comment.