Skip to content

Commit 78bd337

Browse files
committed
Merge branch 'main' into 23-feat-doc-1_0_0-release-documentation-updates
2 parents 67ec749 + 969e0cf commit 78bd337

3 files changed

Lines changed: 129 additions & 2 deletions

File tree

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
using System.IO;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
using Xunit;
5+
using Moq;
6+
using Microsoft.Extensions.Logging;
7+
using Kepware.Api.Model;
8+
using Kepware.Api.Serializer;
9+
using Shouldly;
10+
11+
namespace Kepware.Api.Test.Serializer
12+
{
13+
14+
public class YamlSerializerTests
15+
{
16+
private static YamlSerializer CreateSerializer() =>
17+
new YamlSerializer(new Mock<ILogger<YamlSerializer>>().Object);
18+
19+
[Fact]
20+
public async Task LoadFromYaml_Should_Set_Name_From_Directory()
21+
{
22+
var serializer = CreateSerializer();
23+
var path = Path.Combine(Path.GetTempPath(), "Channel1");
24+
var file = Path.Combine(path, "channel.yaml");
25+
26+
Directory.CreateDirectory(path);
27+
await File.WriteAllTextAsync(file, "description: test");
28+
29+
try
30+
{
31+
var result = await serializer.LoadFromYaml<Channel>(file);
32+
result.Name.ShouldBe("Channel1");
33+
}
34+
finally
35+
{
36+
if (File.Exists(file)) File.Delete(file);
37+
if (Directory.Exists(path)) Directory.Delete(path, true);
38+
}
39+
}
40+
41+
[Fact]
42+
public async Task LoadFromYaml_Should_Create_Default_Entity_When_File_Missing()
43+
{
44+
var serializer = CreateSerializer();
45+
var path = Path.Combine(Path.GetTempPath(), "ChannelMissing");
46+
var file = Path.Combine(path, "missing.yaml");
47+
Directory.CreateDirectory(path);
48+
49+
try
50+
{
51+
var result = await serializer.LoadFromYaml<Channel>(file);
52+
result.ShouldNotBeNull();
53+
result.Name.ShouldBe("ChannelMissing");
54+
}
55+
finally
56+
{
57+
if (Directory.Exists(path)) Directory.Delete(path, true);
58+
}
59+
}
60+
61+
[Fact]
62+
public async Task SaveAsYaml_Should_Not_Overwrite_When_Content_Is_Same()
63+
{
64+
var serializer = CreateSerializer();
65+
var path = Path.Combine(Path.GetTempPath(), "SameContent");
66+
var file = Path.Combine(path, "file.yaml");
67+
68+
var entity = new Channel { Name = "Test" };
69+
await serializer.SaveAsYaml(file, entity);
70+
71+
var initialWriteTime = File.GetLastWriteTimeUtc(file);
72+
await Task.Delay(100); // Ensure timestamp could change
73+
74+
await serializer.SaveAsYaml(file, entity);
75+
File.GetLastWriteTimeUtc(file).ShouldBe(initialWriteTime); // Should not have changed
76+
}
77+
78+
[Fact]
79+
public async Task SaveAsYaml_Should_Write_File_When_Not_Exists()
80+
{
81+
var serializer = CreateSerializer();
82+
var path = Path.Combine(Path.GetTempPath(), "WriteNew");
83+
var file = Path.Combine(path, "new.yaml");
84+
85+
if (Directory.Exists(path)) Directory.Delete(path, true);
86+
var entity = new Channel { Name = "New" };
87+
entity.Description = "New description";
88+
89+
await serializer.SaveAsYaml(file, entity);
90+
File.Exists(file).ShouldBeTrue();
91+
92+
if (File.Exists(file)) File.Delete(file);
93+
if (Directory.Exists(path)) Directory.Delete(path, true);
94+
}
95+
96+
97+
[Fact]
98+
public async Task SaveAsYaml_Should_Delete_File_When_Default_Values()
99+
{
100+
var serializer = CreateSerializer();
101+
var path = Path.Combine(Path.GetTempPath(), "WriteNew");
102+
var file = Path.Combine(path, "new.yaml");
103+
104+
if (Directory.Exists(path)) Directory.Delete(path, true);
105+
var entity = new Channel { Name = "New" };
106+
entity.Description = "New description";
107+
108+
await serializer.SaveAsYaml(file, entity);
109+
File.Exists(file).ShouldBeTrue();
110+
111+
if (File.Exists(file)) File.Delete(file);
112+
if (Directory.Exists(path)) Directory.Delete(path, true);
113+
114+
entity.Description = null; // Set to default value
115+
116+
await serializer.SaveAsYaml(file, entity);
117+
File.Exists(file).ShouldBeFalse();
118+
}
119+
}
120+
}

Kepware.Api/Serializer/YamlSerializer.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using YamlDotNet.Serialization;
99
using Microsoft.Extensions.Logging;
1010
using Kepware.Api.Util;
11+
using System.IO;
1112

1213
namespace Kepware.Api.Serializer
1314
{
@@ -68,7 +69,11 @@ public async Task<T> LoadFromYaml<T>(string filePath, CancellationToken cancella
6869

6970
if (entity is NamedEntity namedEntity)
7071
{
71-
namedEntity.Name = file.DirectoryName!.Split('\\').Last().UnescapeDiskEntry();
72+
if (file.Directory == null)
73+
throw new InvalidOperationException($"Directory of file {filePath} is null");
74+
75+
// Use DirectoryInfo.Name for robust, platform-independent directory name extraction
76+
namedEntity.Name = file.Directory.Name.UnescapeDiskEntry();
7277
}
7378

7479
return entity;
@@ -83,7 +88,7 @@ public async Task<T> LoadFromYaml<T>(string filePath, CancellationToken cancella
8388
public async Task SaveAsYaml(string filePath, object entity, CancellationToken cancellationToken = default)
8489
{
8590
var yaml = _serializer.Serialize(entity);
86-
Directory.CreateDirectory(Path.GetDirectoryName(filePath)!); // Erstelle Verzeichnis, falls es nicht existiert
91+
Directory.CreateDirectory(Path.GetDirectoryName(filePath)!); // Create directory if it doesn't exist
8792

8893
if (yaml.Trim().Equals("{}"))
8994
{

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
[![Build Status](https://github.com/PTCInc/Kepware-ConfigAPI-SDK-dotnet/actions/workflows/dotnet.yml/badge.svg)](https://github.com/PTCInc/Kepware-ConfigAPI-SDK-dotnet/actions)
44
[![Build Status](https://github.com/PTCInc/Kepware-ConfigAPI-SDK-dotnet/actions/workflows/docker-build-and-push.yml/badge.svg)](https://github.com/PTCInc/Kepware-ConfigAPI-SDK-dotnet/actions)
5+
[![NuGet](https://img.shields.io/nuget/v/Kepware.Api.svg)](https://www.nuget.org/packages/Kepware.Api/)
6+
57

68
## Overview
79
The Kepware Configuration API SDK for .NET provides tools and libraries to interact with the Kepware Configuration REST API, enabling configuration management for Kepware servers. This repository includes examples and utilities to streamline development for deployment tools, including a service for continuous synchronization and an API client library.

0 commit comments

Comments
 (0)