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 _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", ma il file reale indicizzato è "uni6592.prt". string percorso = ScriviAsmFinto( "Componente ID 1 (R12--_-_U6592.PRT) x Componente ID 2 (R12--_-_U6592.PRT)"); try { var codici = AssemblyComponentScanner.EstraiCodiciReferenziati(percorso, codiciNoti: new[] { "UNI6592" }); Assert.Contains("UNI6592", codici); Assert.DoesNotContain("R12--_-_U6592", codici); } finally { File.Delete(percorso); } } [Fact] public void File_inesistente_lancia_eccezione_IO() => Assert.Throws(() => 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); } } }