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
197 lines
7.1 KiB
C#
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
|
|
}
|
|
}
|
|
}
|
|
} |