513fa1aa16
Comment/XML-doc changes only: - add summaries to ~10k test methods, fixtures, fakes and helpers (+ <param> on theories, <returns> on async Task methods, <inheritdoc/> on interface implementations the checker can resolve) - strip ~2.6k project-tracking references (WP*, P*-*, row-NN, Task N, #NN, Component-0NN) from comments, keeping the explanatory text; reword false positives in comments only - real docs on fakes implementing BCL/library interfaces (IDisposable, ILogger, IOptionsMonitor, IAsyncLifetime) - reword the last 5 src/ false positives (CWE-1236, failures-1, year-0001, M365) Only non-comment edits: four one-line nested classes split across lines so members can carry docs. Build 0 errors / 0 warnings.
158 lines
5.4 KiB
C#
158 lines
5.4 KiB
C#
using ZB.MOM.WW.ScadaBridge.Commons.Types;
|
|
|
|
namespace ZB.MOM.WW.ScadaBridge.Commons.Tests;
|
|
|
|
public class NativeAlarmSourceOverrideCsvParserTests
|
|
{
|
|
/// <summary>Verifies that a simple file parses into rows with no errors.</summary>
|
|
[Fact]
|
|
public void Parse_SimpleFile_ReturnsRowsNoErrors()
|
|
{
|
|
const string csv =
|
|
"SourceName,Connection,SourceReference,Filter\n" +
|
|
"Pressure,ConnA,ns=2;s=Pump.Alarm,Active\n" +
|
|
"Module.Temp,ConnB,ns=2;s=Temp,\n";
|
|
|
|
var result = NativeAlarmSourceOverrideCsvParser.Parse(csv);
|
|
|
|
Assert.Empty(result.Errors);
|
|
Assert.Equal(2, result.Rows.Count);
|
|
|
|
Assert.Equal("Pressure", result.Rows[0].SourceName);
|
|
Assert.Equal("ConnA", result.Rows[0].Connection);
|
|
Assert.Equal("ns=2;s=Pump.Alarm", result.Rows[0].SourceReference);
|
|
Assert.Equal("Active", result.Rows[0].Filter);
|
|
Assert.Equal(2, result.Rows[0].LineNumber);
|
|
|
|
Assert.Equal("Module.Temp", result.Rows[1].SourceName);
|
|
Assert.Equal("ConnB", result.Rows[1].Connection);
|
|
Assert.Equal("ns=2;s=Temp", result.Rows[1].SourceReference);
|
|
Assert.Null(result.Rows[1].Filter);
|
|
Assert.Equal(3, result.Rows[1].LineNumber);
|
|
}
|
|
|
|
/// <summary>Verifies that blank override fields become null so the inherited value applies.</summary>
|
|
[Fact]
|
|
public void Parse_BlankOverrideFields_BecomeNullInherited()
|
|
{
|
|
const string csv =
|
|
"SourceName,Connection,SourceReference,Filter\n" +
|
|
"Pressure,,,\n";
|
|
|
|
var result = NativeAlarmSourceOverrideCsvParser.Parse(csv);
|
|
|
|
Assert.Empty(result.Errors);
|
|
var row = Assert.Single(result.Rows);
|
|
Assert.Equal("Pressure", row.SourceName);
|
|
Assert.Null(row.Connection);
|
|
Assert.Null(row.SourceReference);
|
|
Assert.Null(row.Filter);
|
|
}
|
|
|
|
/// <summary>Verifies that header names are matched case-insensitively.</summary>
|
|
[Fact]
|
|
public void Parse_HeaderCaseInsensitive_Accepted()
|
|
{
|
|
const string csv =
|
|
"sourcename,CONNECTION,SourceReference,filter\n" +
|
|
"Pressure,ConnA,ref,\n";
|
|
|
|
var result = NativeAlarmSourceOverrideCsvParser.Parse(csv);
|
|
|
|
Assert.Empty(result.Errors);
|
|
Assert.Single(result.Rows);
|
|
}
|
|
|
|
/// <summary>Verifies that a quoted field preserves an embedded comma.</summary>
|
|
[Fact]
|
|
public void Parse_QuotedFieldWithComma_PreservesEmbeddedComma()
|
|
{
|
|
const string csv =
|
|
"SourceName,Connection,SourceReference,Filter\n" +
|
|
"Pressure,ConnA,\"ns=2;s=a,b,c\",Active\n";
|
|
|
|
var result = NativeAlarmSourceOverrideCsvParser.Parse(csv);
|
|
|
|
Assert.Empty(result.Errors);
|
|
var row = Assert.Single(result.Rows);
|
|
Assert.Equal("ns=2;s=a,b,c", row.SourceReference);
|
|
}
|
|
|
|
/// <summary>Verifies that a missing header returns a header error.</summary>
|
|
[Fact]
|
|
public void Parse_MissingHeader_ReturnsHeaderError()
|
|
{
|
|
const string csv = "Pressure,ConnA,ref,Active\n";
|
|
|
|
var result = NativeAlarmSourceOverrideCsvParser.Parse(csv);
|
|
|
|
Assert.Empty(result.Rows);
|
|
var error = Assert.Single(result.Errors);
|
|
Assert.Contains("SourceName,Connection,SourceReference,Filter", error);
|
|
}
|
|
|
|
/// <summary>Verifies that a row with the wrong column count reports a per-line error and is skipped.</summary>
|
|
[Fact]
|
|
public void Parse_WrongColumnCount_ReportsPerLineErrorAndSkipsRow()
|
|
{
|
|
const string csv =
|
|
"SourceName,Connection,SourceReference,Filter\n" +
|
|
"Pressure,ConnA\n" +
|
|
"Temp,ConnB,ref,Active\n";
|
|
|
|
var result = NativeAlarmSourceOverrideCsvParser.Parse(csv);
|
|
|
|
var error = Assert.Single(result.Errors);
|
|
Assert.Contains("Line 2", error);
|
|
Assert.Contains("expected 4 columns", error);
|
|
// Valid rows still flow through.
|
|
var row = Assert.Single(result.Rows);
|
|
Assert.Equal("Temp", row.SourceName);
|
|
}
|
|
|
|
/// <summary>Verifies that a blank source name reports an error.</summary>
|
|
[Fact]
|
|
public void Parse_BlankSourceName_ReportsError()
|
|
{
|
|
const string csv =
|
|
"SourceName,Connection,SourceReference,Filter\n" +
|
|
",ConnA,ref,Active\n";
|
|
|
|
var result = NativeAlarmSourceOverrideCsvParser.Parse(csv);
|
|
|
|
Assert.Empty(result.Rows);
|
|
var error = Assert.Single(result.Errors);
|
|
Assert.Contains("SourceName must not be blank", error);
|
|
}
|
|
|
|
/// <summary>Verifies that an unterminated quote reports an error.</summary>
|
|
[Fact]
|
|
public void Parse_UnterminatedQuote_ReportsError()
|
|
{
|
|
const string csv =
|
|
"SourceName,Connection,SourceReference,Filter\n" +
|
|
"Pressure,ConnA,\"ns=2;s=open,Active\n";
|
|
|
|
var result = NativeAlarmSourceOverrideCsvParser.Parse(csv);
|
|
|
|
Assert.Empty(result.Rows);
|
|
Assert.Contains(result.Errors, e => e.Contains("Unterminated quoted field"));
|
|
}
|
|
|
|
/// <summary>Verifies that blank lines are skipped without an error.</summary>
|
|
[Fact]
|
|
public void Parse_BlankLinesSkippedWithoutError()
|
|
{
|
|
const string csv =
|
|
"SourceName,Connection,SourceReference,Filter\n" +
|
|
"\n" +
|
|
"Pressure,ConnA,ref,Active\n" +
|
|
" \n";
|
|
|
|
var result = NativeAlarmSourceOverrideCsvParser.Parse(csv);
|
|
|
|
Assert.Empty(result.Errors);
|
|
Assert.Single(result.Rows);
|
|
}
|
|
}
|