Skip to content

Commit 662c40b

Browse files
committed
Initial Commit.
1 parent fbe5eb9 commit 662c40b

15 files changed

Lines changed: 431 additions & 20 deletions

.github/FUNDING.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# These are supported funding model platforms
2+
3+
ko_fi: tensiondev

.github/dependabot.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# To get started with Dependabot version updates, you'll need to specify which
2+
# package ecosystems to update and where the package manifests are located.
3+
# Please see the documentation for all configuration options:
4+
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5+
6+
version: 2
7+
updates:
8+
- package-ecosystem: "nuget" # See documentation for possible values
9+
directory: "/" # Location of package manifests
10+
schedule:
11+
interval: "monthly"

.github/workflows/dotnet.yml

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
name: .NET
2+
3+
on:
4+
push:
5+
branches: [ "**" ]
6+
pull_request:
7+
branches: [ "master" ]
8+
9+
jobs:
10+
build:
11+
12+
runs-on: windows-latest
13+
14+
strategy:
15+
matrix:
16+
dotnet: [ '8.0.x' ]
17+
name: .NET ${{ matrix.dotnet }}
18+
19+
steps:
20+
- name: Set up JDK 17
21+
uses: actions/setup-java@v4
22+
with:
23+
java-version: 17
24+
distribution: 'zulu' # Alternative distribution options are available.
25+
- uses: actions/checkout@v4
26+
with:
27+
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
28+
- name: Setup .NET
29+
uses: actions/setup-dotnet@v4
30+
with:
31+
dotnet-version: ${{ matrix.dotnet }}
32+
- name: Cache SonarQube Cloud packages
33+
uses: actions/cache@v4
34+
with:
35+
path: ~\sonar\cache
36+
key: ${{ runner.os }}-sonar
37+
restore-keys: ${{ runner.os }}-sonar
38+
- name: Cache SonarQube Cloud scanner
39+
id: cache-sonar-scanner
40+
uses: actions/cache@v4
41+
with:
42+
path: .\.sonar\scanner
43+
key: ${{ runner.os }}-sonar-scanner
44+
restore-keys: ${{ runner.os }}-sonar-scanner
45+
- name: Install SonarQube Cloud scanner
46+
if: steps.cache-sonar-scanner.outputs.cache-hit != 'true'
47+
shell: powershell
48+
run: |
49+
New-Item -Path .\.sonar\scanner -ItemType Directory
50+
dotnet tool update dotnet-sonarscanner --tool-path .\.sonar\scanner
51+
- name: Restore dependencies
52+
run: dotnet restore
53+
- name: SonarCloudPrepare
54+
env:
55+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
56+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
57+
run: .\.sonar\scanner\dotnet-sonarscanner begin /k:"TensionDev_UUID.Serialization.JsonNet" /o:"tensiondev" /d:sonar.token="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.scanner.scanAll=false /d:sonar.cs.opencover.reportsPaths=**/coverage.opencover.xml
58+
- name: Build
59+
run: dotnet build --no-restore
60+
- name: Test
61+
run: dotnet test --no-build --verbosity normal --collect "XPlat Code Coverage;Format=opencover"
62+
- name: SonarCloudAnalyze
63+
env:
64+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
65+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
66+
run: .\.sonar\scanner\dotnet-sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}"
67+
68+
test:
69+
70+
strategy:
71+
matrix:
72+
dotnet: [ '8.0.x' ]
73+
os: [macos-latest, ubuntu-latest, windows-latest]
74+
75+
runs-on: ${{ matrix.os }}
76+
77+
name: .NET ${{ matrix.dotnet }} on ${{ matrix.os }}
78+
79+
steps:
80+
- uses: actions/checkout@v4
81+
with:
82+
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
83+
- name: Setup .NET
84+
uses: actions/setup-dotnet@v4
85+
with:
86+
dotnet-version: ${{ matrix.dotnet }}
87+
- name: Restore dependencies
88+
run: dotnet restore
89+
- name: Build
90+
run: dotnet build --no-restore
91+
- name: Test
92+
run: dotnet test --no-build --verbosity normal --collect "XPlat Code Coverage;Format=opencover"
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# This is a basic workflow to help you get started with Actions
2+
3+
name: Package Release
4+
5+
# Controls when the workflow will run
6+
on:
7+
# Triggers the workflow on push events but only for the tags
8+
push:
9+
tags:
10+
- v[0-9]+.[0-9]+.[0-9]+
11+
- v[0-9]+.[0-9]+.[0-9]+-alpha
12+
- v[0-9]+.[0-9]+.[0-9]+-beta
13+
14+
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
15+
jobs:
16+
# This workflow contains a single job called "build"
17+
build:
18+
# The type of runner that the job will run on
19+
runs-on: ubuntu-latest
20+
21+
# Steps represent a sequence of tasks that will be executed as part of the job
22+
steps:
23+
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
24+
- uses: actions/checkout@v4
25+
26+
- name: Setup .NET 8
27+
uses: actions/setup-dotnet@v3
28+
with:
29+
dotnet-version: 8.0.x
30+
source-url: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json
31+
env:
32+
NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
33+
34+
- name: Restore dependencies
35+
run: dotnet restore
36+
37+
- name: Build
38+
run: dotnet build --no-restore
39+
40+
- name: Build Release
41+
run: dotnet build --configuration Release --no-restore
42+
43+
- name: Pack
44+
run: dotnet pack --configuration Release
45+
46+
- name: Push NuGet
47+
run: dotnet nuget push "TensionDev.UUID.Serialization.JsonNet/bin/Release/*.nupkg" --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_TOKEN }} --no-symbols --skip-duplicate

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# TensionDev.UUID.Serialization.JsonNet
2+
3+
# Changelog
4+
All notable changes to this project will be documented in this file.
5+
6+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
7+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
8+
9+
## [Unreleased]
10+
11+
### Added
12+
- Added UuidJsonNetConverter for Json serialization and deserialization.
File renamed without changes.

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
1-
# UUID.Serialization.JsonNet
1+
# TensionDev.UUID.Serialization.JsonNet
2+
3+
[![.NET](https://github.com/TensionDev/UUID.Serialization.JsonNet/actions/workflows/dotnet.yml/badge.svg)](https://github.com/TensionDev/UUID.Serialization.JsonNet/actions/workflows/dotnet.yml)
4+
[![Package Release](https://github.com/TensionDev/UUID.Serialization.JsonNet/actions/workflows/package-release.yml/badge.svg)](https://github.com/TensionDev/UUID.Serialization.JsonNet/actions/workflows/package-release.yml)
5+
[![CodeQL](https://github.com/TensionDev/UUID.Serialization.JsonNet/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/TensionDev/UUID.Serialization.JsonNet/actions/workflows/github-code-scanning/codeql)
6+
7+
TensionDev.UUID.Serialization.JsonNet is a .NET library for serializing and deserializing with Universally Unique Identifiers (UUIDs) using Json.NET.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
6+
<IsPackable>false</IsPackable>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
11+
<PackageReference Include="Moq" Version="4.18.4" />
12+
<PackageReference Include="xunit" Version="2.9.3" />
13+
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">
14+
<PrivateAssets>all</PrivateAssets>
15+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
16+
</PackageReference>
17+
<PackageReference Include="coverlet.collector" Version="6.0.4">
18+
<PrivateAssets>all</PrivateAssets>
19+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
20+
</PackageReference>
21+
</ItemGroup>
22+
23+
<ItemGroup>
24+
<ProjectReference Include="..\TensionDev.UUID.Serialization.JsonNet\TensionDev.UUID.Serialization.JsonNet.csproj" />
25+
</ItemGroup>
26+
27+
</Project>
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
using Moq;
2+
using Newtonsoft.Json;
3+
using System;
4+
using Xunit;
5+
6+
namespace TensionDev.UUID.Serialization.JsonNet.Tests
7+
{
8+
public class TestUuidJsonNetConverter : IDisposable
9+
{
10+
private bool disposedValue;
11+
12+
private readonly UuidJsonNetConverter _converter;
13+
14+
public TestUuidJsonNetConverter()
15+
{
16+
_converter = new UuidJsonNetConverter();
17+
}
18+
19+
[Fact]
20+
public void TestReadJson()
21+
{
22+
// Arrange
23+
const string validUuidString = "00000000-0000-0000-0000-000000000000";
24+
var readerMock = new Mock<JsonReader>(MockBehavior.Strict);
25+
readerMock.SetupGet(r => r.TokenType).Returns(JsonToken.String);
26+
readerMock.SetupGet(r => r.Value).Returns((object)validUuidString);
27+
28+
var converter = new UuidJsonNetConverter();
29+
30+
// existingValue must be non-nullable; obtain an instance via Parse to satisfy parameter constraints.
31+
Uuid existingValue = Uuid.Parse(validUuidString);
32+
var serializer = new JsonSerializer();
33+
34+
// Act
35+
Uuid result = converter.ReadJson(readerMock.Object, typeof(Uuid), existingValue, hasExistingValue: false, serializer: serializer);
36+
37+
// Assert
38+
Assert.NotNull(result);
39+
Assert.Equal(validUuidString, result.ToString());
40+
}
41+
42+
[Fact]
43+
public void TestWriteJson()
44+
{
45+
var writerMock = new Mock<JsonWriter>(MockBehavior.Strict);
46+
object? capturedValue = null;
47+
// Setup to accept any object and capture it
48+
writerMock.Setup(w => w.WriteValue(It.IsAny<string?>()))
49+
.Callback<string?>(v => capturedValue = v)
50+
.Verifiable();
51+
52+
var serializerMock = new Mock<JsonSerializer>(MockBehavior.Loose);
53+
54+
// Attempt to create an instance of the Uuid type.
55+
// This will succeed for structs and for classes with a public parameterless constructor.
56+
// If it fails, mark test inconclusive because we cannot safely fabricate the dependency.
57+
TensionDev.UUID.Uuid value;
58+
try
59+
{
60+
var instance = Activator.CreateInstance(typeof(TensionDev.UUID.Uuid));
61+
if (instance == null)
62+
{
63+
// This can happen if the type is a non-instantiable class (abstract) or Activator returns null.
64+
Assert.Fail("Could not create an instance of TensionDev.UUID.Uuid (Activator.CreateInstance returned null). Provide a parameterless constructor or update the test environment.");
65+
return;
66+
}
67+
68+
value = (TensionDev.UUID.Uuid)instance;
69+
}
70+
catch (Exception ex)
71+
{
72+
// xUnit does not provide Assert.Inconclusive; use Assert.Fail to report the diagnostic and stop the test.
73+
Assert.Fail("Could not create an instance of TensionDev.UUID.Uuid: " + ex.Message);
74+
return;
75+
}
76+
77+
// Act
78+
_converter.WriteJson(writerMock.Object, value, serializerMock.Object);
79+
80+
// Assert
81+
writerMock.Verify(w => w.WriteValue(It.IsAny<string?>()), Times.Once, "WriteValue should be called exactly once.");
82+
// Ensure the captured value matches the value.ToString() result
83+
var expected = value.ToString();
84+
Assert.NotNull(capturedValue);
85+
Assert.Equal(expected, capturedValue?.ToString());
86+
}
87+
88+
protected virtual void Dispose(bool disposing)
89+
{
90+
if (!disposedValue)
91+
{
92+
if (disposing)
93+
{
94+
// TODO: dispose managed state (managed objects)
95+
}
96+
97+
// TODO: free unmanaged resources (unmanaged objects) and override finalizer
98+
// TODO: set large fields to null
99+
disposedValue = true;
100+
}
101+
}
102+
103+
// // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
104+
// ~TestUuidJsonNetConverter()
105+
// {
106+
// // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
107+
// Dispose(disposing: false);
108+
// }
109+
110+
public void Dispose()
111+
{
112+
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
113+
Dispose(disposing: true);
114+
GC.SuppressFinalize(this);
115+
}
116+
}
117+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Microsoft Visual Studio Solution File, Format Version 12.00
2+
# Visual Studio Version 18
3+
VisualStudioVersion = 18.3.11505.172 d18.3
4+
MinimumVisualStudioVersion = 10.0.40219.1
5+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TensionDev.UUID.Serialization.JsonNet", "TensionDev.UUID.Serialization.JsonNet\TensionDev.UUID.Serialization.JsonNet.csproj", "{EB9DE634-1BD3-94ED-67A5-716D96836CD5}"
6+
EndProject
7+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TensionDev.UUID.Serialization.JsonNet.Tests", "TensionDev.UUID.Serialization.JsonNet.Tests\TensionDev.UUID.Serialization.JsonNet.Tests.csproj", "{4320C58F-7522-E41C-CF00-806882AE47D0}"
8+
EndProject
9+
Global
10+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
11+
Debug|Any CPU = Debug|Any CPU
12+
Release|Any CPU = Release|Any CPU
13+
EndGlobalSection
14+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
15+
{EB9DE634-1BD3-94ED-67A5-716D96836CD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
16+
{EB9DE634-1BD3-94ED-67A5-716D96836CD5}.Debug|Any CPU.Build.0 = Debug|Any CPU
17+
{EB9DE634-1BD3-94ED-67A5-716D96836CD5}.Release|Any CPU.ActiveCfg = Release|Any CPU
18+
{EB9DE634-1BD3-94ED-67A5-716D96836CD5}.Release|Any CPU.Build.0 = Release|Any CPU
19+
{4320C58F-7522-E41C-CF00-806882AE47D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
20+
{4320C58F-7522-E41C-CF00-806882AE47D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
21+
{4320C58F-7522-E41C-CF00-806882AE47D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
22+
{4320C58F-7522-E41C-CF00-806882AE47D0}.Release|Any CPU.Build.0 = Release|Any CPU
23+
EndGlobalSection
24+
GlobalSection(SolutionProperties) = preSolution
25+
HideSolutionNode = FALSE
26+
EndGlobalSection
27+
EndGlobal

0 commit comments

Comments
 (0)