Files
prep-step/PrepStep.Tests/AssemblyComponentScannerTests.cs
T
davideandClaude Sonnet 5 13798ad47c Add explicit working folder; rename project from CadSearchGui to PrepStep
Working folder (phase 1): CSV/raw/step/step_finali all used to live split
across two different implicit locations (CSV in the "repo root" found by
walking up for CLAUDE.md, raw/step next to the input distinta file) with
neither shown to the user. That repo-root lookup also silently breaks once
the app runs as a standalone published exe on a machine with no repo/
CLAUDE.md at all. Replaced both with one explicit "cartella di lavoro",
auto-suggested (last used, remembered the same way as the DB path) and
changeable from phase 1, with no dependency on any repo marker file.

Rename: CadSearchGui was the working name from before the app had a
product identity; renamed folders, csproj files, namespace and the
AppData settings folder to PrepStep throughout, matching the exe name
already in use. Product-facing name stays "Cevolani StepPrep".

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 11:18:43 +02:00

152 lines
5.9 KiB
C#

using PrepStep;
namespace PrepStep.Tests;
public class AssemblyComponentScannerTests
{
private static string ScriviAsmFinto(string testo)
{
string percorso = Path.GetTempFileName();
File.WriteAllBytes(percorso, System.Text.Encoding.Latin1.GetBytes(testo));
return percorso;
}
[Fact]
public void Scarta_codici_con_una_sola_occorrenza()
{
// "11112222" compare 2 volte con un vero placement (riferimento vero), "99998888"
// una sola volta senza placement (rumore).
string percorso = ScriviAsmFinto(
"blah Componente ID 1 (11112222.PRT) blah 99998888 blah 11112222 fine");
try
{
var codici = AssemblyComponentScanner.EstraiCodiciReferenziati(percorso);
Assert.Contains("11112222", codici);
Assert.DoesNotContain("99998888", codici);
}
finally { File.Delete(percorso); }
}
[Fact]
public void Scarta_codice_ripetuto_senza_un_vero_placement()
{
// Riferimento al nome di un altro assieme (es. il padre che lo contiene): ripetuto
// più volte ma mai dentro un placement "Componente ID N (...)" - va scartato.
string percorso = ScriviAsmFinto("padre 33334444 assieme 33334444_D200 33334444");
try
{
var codici = AssemblyComponentScanner.EstraiCodiciReferenziati(percorso);
Assert.DoesNotContain("33334444", codici);
}
finally { File.Delete(percorso); }
}
[Fact]
public void Riconosce_sotto_assiemi_con_suffisso_stile_D100()
{
// Visto su 9244228573.asm: i sotto-assiemi hanno nomi come <codice>_D100/_D200/_D300.
string percorso = ScriviAsmFinto("x 9244228573_D100 y 9244228573_D100 z 9244228573_D200 9244228573_D200");
try
{
var codici = AssemblyComponentScanner.EstraiCodiciReferenziati(percorso);
Assert.Contains("9244228573_D100", codici);
Assert.Contains("9244228573_D200", codici);
}
finally { File.Delete(percorso); }
}
[Fact]
public void Non_estrae_nulla_da_una_sequenza_di_cifre_troppo_lunga()
{
// Una sequenza di 15 cifre di fila non contiene nessun confine di parola valido
// per un blocco di 8-12 cifre: non deve produrre falsi positivi troncati.
string percorso = ScriviAsmFinto("123456789012345 123456789012345");
try
{
var codici = AssemblyComponentScanner.EstraiCodiciReferenziati(percorso);
Assert.Empty(codici);
}
finally { File.Delete(percorso); }
}
[Fact]
public void Scarta_id_di_viste_salvate_ModelView()
{
// Visto su 9044207061.asm: "ModelView#1073741828" compare più volte ma è un ID
// interno di vista salvata, non un codice componente.
string percorso = ScriviAsmFinto("x ModelView#1073741828 y ModelView#1073741828 z");
try
{
var codici = AssemblyComponentScanner.EstraiCodiciReferenziati(percorso);
Assert.DoesNotContain("1073741828", codici);
}
finally { File.Delete(percorso); }
}
[Fact]
public void Estrae_il_codice_generico_da_istanze_di_family_table_UNI()
{
// Visto su 9244228576.asm: le viti normalizzate compaiono come istanza di family
// table "R12--_-_U6592<UNI6592>", ma il file reale indicizzato è "uni6592.prt".
string percorso = ScriviAsmFinto(
"Componente ID 1 (R12--_-_U6592<UNI6592>.PRT) x Componente ID 2 (R12--_-_U6592<UNI6592>.PRT)");
try
{
var codici = AssemblyComponentScanner.EstraiCodiciReferenziati(percorso, codiciNoti: new[] { "UNI6592" });
Assert.Contains("UNI6592", codici);
Assert.DoesNotContain("R12--_-_U6592<UNI6592>", codici);
}
finally { File.Delete(percorso); }
}
[Fact]
public void File_inesistente_lancia_eccezione_IO() =>
Assert.Throws<DirectoryNotFoundException>(() =>
AssemblyComponentScanner.EstraiCodiciReferenziati(@"C:\non\esiste\pippo.asm.1"));
[Fact]
public void Riconosce_parte_commerciale_con_nome_alfabetico_se_nel_db()
{
// Visto su un caso reale: le parti commerciali scaricate come STEP (es. anelli,
// boccole) hanno nomi Creo alfabetici, non un codice numerico Pro-E - si
// riconoscono solo se il nome esiste davvero come codice indicizzato.
string percorso = ScriviAsmFinto(
"blah Componente ID 11 (ANELLO_ESTERNO-1-SOLID1.PRT) blah RUMORE_CASUALE blah");
try
{
var codiciNoti = new[] { "ANELLO_ESTERNO-1-SOLID1" };
var codici = AssemblyComponentScanner.EstraiCodiciReferenziati(percorso, codiciNoti);
Assert.Contains("ANELLO_ESTERNO-1-SOLID1", codici);
}
finally { File.Delete(percorso); }
}
[Fact]
public void Scarta_token_alfabetico_nel_db_ma_senza_placement()
{
// Un token che coincide per puro caso con un codice DB corto/generico (es. una
// keyword interna di Creo) non basta: senza un vero placement resta rumore.
string percorso = ScriviAsmFinto("start_part blah blah start_part");
try
{
var codiciNoti = new[] { "start_part" };
var codici = AssemblyComponentScanner.EstraiCodiciReferenziati(percorso, codiciNoti);
Assert.DoesNotContain("start_part", codici);
}
finally { File.Delete(percorso); }
}
[Fact]
public void Ignora_token_alfabetici_non_presenti_nel_db()
{
string percorso = ScriviAsmFinto(
"blah Componente ID 1 (QUALCOSA_DI_INESISTENTE-1.PRT) blah");
try
{
var codici = AssemblyComponentScanner.EstraiCodiciReferenziati(percorso, codiciNoti: new[] { "ALTRO_CODICE" });
Assert.DoesNotContain("QUALCOSA_DI_INESISTENTE-1", codici);
}
finally { File.Delete(percorso); }
}
}