Files
Christoph Schwörer f045b99a25 Codebasis als Dateien ins Arbeitsrepo statt als Gitlink
QuellCode/CentronERP war nur als Gitlink (Submodul-Referenz auf 79c1142)
getrackt, ohne .gitmodules und ohne erreichbares Remote. Der
Untersuchungsgegenstand der Versuchsreihe war damit nicht reproduzierbar
gesichert: Ein Klon haette ein leeres Verzeichnis erhalten, und die Belege
der 3.287 Anforderungen waeren nicht ueberpruefbar gewesen.

Umstellung:
- Historie nach c:\DEV\CentronERP_git_snapshot_79c1142 ausgelagert
  (vollstaendig lesbar, enthaelt 79c1142 und Vorgaenger 89ccfd6)
- Gitlink aus dem Index entfernt
- Dateiinhalt aufgenommen: 24.557 Dateien, rund 333 MB

Die verschachtelte .gitignore der Codebasis gilt weiter, Build-Artefakte
bleiben ausgeschlossen. Details in Versuche/Versuch_01/_Codebasis-Nachweis.md
2026-08-26 07:43:51 +02:00

197 lines
7.1 KiB
C#

using Centron.DAO;
using Centron.Data.WebServices.Sales.Receipts;
using Centron.Tests.EndToEnd.Infrastructure.Verifier;
using DevExpress.CodeParser;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows.Forms;
using Xunit;
using Centron.Core;
using Centron.Core.Utils;
using DevExpress.Spreadsheet;
namespace Centron.Tests.EndToEnd.Infrastructure.Verifier
{
public class CentronVerifier
{
public CentronVerifier()
{
this.Settings = new CentronVerifierSettings();
this.Settings.IgnoreProperty<ReceiptBaseDTO>(f => f.CreatedThroughApplicationVersion);
this.Settings.IgnoreProperty<ReceiptBaseDTO>(f => f.ChangedThroughApplicationVersion);
}
public CentronVerifierSettings Settings { get; }
public bool OverrideExpectedFiles { get; set; }
public void VerifyTable(string name, string tableName, string where = null, CentronVerifierSettings settings = null, [CallerFilePath] string sourceFile = "")
{
where = where ?? "1 = 1";
string sqlStatement = $"SELECT * FROM {tableName} WHERE {where}";
this.VerifySql(name, sqlStatement, settings, sourceFile);
}
public void VerifySql(string name, string sqlStatement, CentronVerifierSettings settings = null, [CallerFilePath] string sourceFile = "")
{
using (var session = new DAOSession())
{
var table = session.Advanced.RawSqlAccess.GetRawSqlResult(sqlStatement);
this.Verify(name, table, settings, sourceFile: sourceFile);
}
}
public void VerifyExcel(string fileName, byte[] excel, [CallerFilePath] string sourceFile = "")
{
var workbook = new Workbook();
workbook.LoadDocument(excel);
var worksheet = workbook.Worksheets[0];
string[,] excelCellValues = new string[worksheet.Rows.LastUsedIndex + 1, worksheet.Columns.LastUsedIndex + 1];
for (int i = 0; i <= worksheet.Rows.LastUsedIndex; i++)
for (int j = 0; j <= worksheet.Columns.LastUsedIndex; j++)
{
var testCell = worksheet.Cells[i, j].Value.ToString();
excelCellValues[i, j] = testCell;
}
this.Verify(fileName, excelCellValues, sourceFile: sourceFile);
}
public void Verify(string name, object data, CentronVerifierSettings settings = null, [CallerFilePath] string sourceFile = "")
{
Guard.NotNullOrWhiteSpace(name, nameof(name));
//data can be NULL
//differentPerTargetFramework can be anything
//settings can be NULL
Guard.NotNullOrWhiteSpace(sourceFile, nameof(sourceFile));
if (settings != null)
{
settings.MergeWith(this.Settings);
}
else
{
settings = this.Settings;
}
var json = this.SerializeAsJson(data, settings);
var expectedFileName = this.GetExpectedFileName(name, sourceFile);
var actualFileName = this.GetActualFileName(name, sourceFile);
var directory = Path.GetDirectoryName(expectedFileName);
if (Directory.Exists(directory) == false)
Directory.CreateDirectory(directory);
if (this.OverrideExpectedFiles)
{
File.WriteAllText(expectedFileName, json, Encoding.UTF8);
return;
}
File.WriteAllText(actualFileName, json, Encoding.UTF8);
var expected = File.Exists(expectedFileName)
? File.ReadAllText(expectedFileName, Encoding.UTF8)
: string.Empty;
expected = expected.Replace(@"\r", @"");
json = json.Replace(@"\r", @"");
try
{
Assert.Equal(expected, json, ignoreLineEndingDifferences:true);
}
catch (Exception e)
{
if(Debugger.IsAttached)
this.StartDiffTool(expectedFileName, actualFileName);
Console.WriteLine(json);
throw new Exception(name + " failed", e);
}
}
private string SerializeAsJson(object data, CentronVerifierSettings verifierSettings)
{
var settings = new JsonSerializerSettings
{
Formatting = Newtonsoft.Json.Formatting.Indented,
Converters = new List<JsonConverter>
{
verifierSettings.CleanupGuidValues ? new CleanupValuesConverter<Guid>() : null,
verifierSettings.CleanupDateTimeValues ? new CleanupValuesConverter<DateTime>(new DateTimeEqualityComparer()) : null,
verifierSettings.CleanupDateTimeOffsetValues ? new CleanupValuesConverter<DateTimeOffset>(new DateTimeOffsetEqualityComparer()) : null,
}
.Where(f => f != null)
.ToList(),
ContractResolver = verifierSettings.GetContractResolver(),
};
var ignoredColumns = verifierSettings.GetIgnoredColumns();
if (ignoredColumns.Any() && data is DataTable table)
{
foreach (var ignoredColumn in ignoredColumns)
{
if (table.Columns.Contains(ignoredColumn))
table.Columns.Remove(ignoredColumn);
}
}
var serializer = JsonSerializer.Create(settings);
var builder = new StringBuilder();
using (var stringWriter = new StringWriter(builder))
using (var writer = new JsonTextWriter(stringWriter) { QuoteChar = '\'', QuoteName = false })
{
serializer.Serialize(writer, data);
}
builder.Replace(@"\\", @"\");
return builder.ToString();
}
private string GetExpectedFileName(string name, string sourceFile)
{
return $"{Path.GetDirectoryName(sourceFile)}/{name}.expected.txt";
}
private string GetActualFileName(string name, string sourceFile)
{
return $"{Path.GetDirectoryName(sourceFile)}/{name}.actual.txt";
}
private void StartDiffTool(string expectedFileName, string actualFileName)
{
try
{
if (File.Exists(expectedFileName) == false || File.Exists(actualFileName) == false)
return;
string vsPath = @"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\devenv.exe";
if (File.Exists(vsPath))
ProcessHelper.Start(vsPath, $"/diff \"{actualFileName}\" \"{expectedFileName}\"");
else
ProcessHelper.Start("code", $"--diff \"{actualFileName}\" \"{expectedFileName}\"");
}
catch (Exception)
{
//Ooops
}
}
}
}