verificare partener: garda pe cont NULL, hook-uri de disciplina, docs compactate
- ooperatii_comune: verific_partener nu mai construieste SQL NULL cand contul primit e NULL (EMPTY(.NULL.) e .F. in VFP) - utile\context_watch.ps1 si utile\docs_revizie_check.ps1: masurarea contextului sesiunii si cadenta reviziei de documentatie, prin hook-uri Claude Code (instalare in docs\monitorizare-context.md) - reguli_lucru: delegare la subagenti, modificari minime si scoped, scrierea si revizuirea documentatiei, changelog strictul necesar (regulile 3, 6, 9, 11, 12) - scripturi-migrare-db: continutul unui script (scoped, fara select, idempotent) - teste noi pentru cele doua erori din achizitia de import - restul documentatiei compactata, fara pierdere de reguli Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RYbiinqXxdEqXi53x4Ro7K
This commit is contained in:
@@ -11,11 +11,11 @@ Fisiere in `COMUN\utile\Teste\`: `vfp_ui_harness.ps1` (orchestrator generic, par
|
||||
`mock_amessagebox.prg` (mock dialog) — infrastructura sta in radacina `Teste\`; suitele stau in
|
||||
subfoldere pe subiect. Exemplu complet: `achizitie_import\test_import_nota_ui.prg` + `.ps1`.
|
||||
|
||||
**REGULA (Marius, 17/07/2026): testele pe aplicatii frontend exerseaza fluxul REAL al
|
||||
**REGULA (Marius): testele pe aplicatii frontend exerseaza fluxul REAL al
|
||||
utilizatorului** — formularul/butonul/metoda pe care o apeleaza aplicatia, NU introducerea
|
||||
directa a randurilor in cursoare/tabele. Popularea directa sare peste validari/filtre/efecte
|
||||
laterale si da PASS fals (caz real: un articol "adaugat" direct in cursor trecea testul, dar
|
||||
prin fluxul real nu se adauga deloc). Mock-urile raman permise doar pe INFRASTRUCTURA (Oracle,
|
||||
laterale si da PASS fals (caz real: articol "adaugat" direct in cursor trecea testul, dar prin
|
||||
fluxul real nu se adauga deloc). Mock-urile raman permise doar pe INFRASTRUCTURA (Oracle,
|
||||
dialoguri modale), nu pe pasii fluxului testat.
|
||||
|
||||
## Test UI nou in 5 pasi
|
||||
@@ -33,7 +33,7 @@ dialoguri modale), nu pe pasii fluxului testat.
|
||||
5. `powershell -File vfp_ui_harness.ps1 -TestPrg <test.prg> -Steps @('pas0',...)`.
|
||||
PNG-uri in `screenshots\step_<n>_<eticheta>.png`; log in `<test>_log.txt`.
|
||||
|
||||
## Capcane / deblocari (toate confirmate in sesiune)
|
||||
## Capcane / deblocari
|
||||
|
||||
a. **`SET SAFETY OFF` + `SET TALK OFF` inaintea primului `STRTOFILE`.** Cu SAFETY ON, scrierea
|
||||
log-ului existent scoate un dialog modal care blocheaza rularea (proces viu, "instanta
|
||||
@@ -51,22 +51,20 @@ d. **`vfp9 -A test.prg` deschide INTERMITENT editorul** in loc sa ruleze (log go
|
||||
`.fxp`-ul PRECOMPILAT. Precompilarea (`COMPILE`+`QUIT`) atarna dupa COMPILE si, rulata in
|
||||
ACEEASI sesiune powershell, otraveste lansarile ulterioare - ruleaza-o intr-un proces copil
|
||||
izolat (`Start-Process -Wait _precompile.ps1`).
|
||||
e. **Suitele NU se ruleaza in paralel** intre ele: harness-ul isi omoara instantele `vfp9`
|
||||
ramase inainte de fiecare lansare, deci un al doilea test pornit peste primul il ucide.
|
||||
Omorarea e INSA filtrata pe linia de comanda (`Win32_Process.CommandLine` care contine
|
||||
folderul de teste): instantele `vfp9` straine — sesiunea IDE a utilizatorului sau teste
|
||||
dintr-un ALT proiect VFP — nu sunt atinse si nu blocheaza rularea. Nu reintroduce
|
||||
`Get-Process vfp9 | Stop-Process -Force` fara filtru.
|
||||
f. **FARA FURT DE FOCUS (17/07/2026)**: `Graphics.CopyFromScreen` fura focus si se corupe daca
|
||||
utilizatorul lucreaza in paralel - nu se mai foloseste. Capturile se fac cu `PrintWindow`
|
||||
(user32, P/Invoke) pe `Process.MainWindowHandle`, flag `2` = `PW_RENDERFULLCONTENT`
|
||||
(fallback `0` daca iese goala); merge cu fereastra acoperita, dar NU minimizata. Fereastra
|
||||
se muta OFF-SCREEN (`SetWindowPos`, `HWND_BOTTOM`, x=-4000, `SWP_NOACTIVATE`) imediat ce
|
||||
apare handle-ul si SE RE-IMPINGE la fiecare pas (VFP se reactiveaza singur la
|
||||
`Show()`/dialoguri). Consolele powershell copil sunt `-WindowStyle Hidden` (sigur pentru
|
||||
consola, NU pentru GUI VFP - ascunsa, `PrintWindow` poate reda gol). Implementat in
|
||||
`vfp_ui_harness.ps1` (Take-Screenshot, Push-Offscreen, Wait-MainWindowHandle) si
|
||||
`_precompile.ps1`.
|
||||
e. **Suitele NU se ruleaza in paralel**: harness-ul omoara instantele `vfp9` ramase inainte de
|
||||
fiecare lansare, deci un al doilea test pornit peste primul il ucide. Omorarea e filtrata pe
|
||||
linia de comanda (`Win32_Process.CommandLine` contine folderul de teste): instantele `vfp9`
|
||||
straine (sesiunea IDE a utilizatorului, teste dintr-un ALT proiect VFP) nu sunt atinse. Nu
|
||||
reintroduce `Get-Process vfp9 | Stop-Process -Force` fara filtru.
|
||||
f. **FARA FURT DE FOCUS**: `Graphics.CopyFromScreen` fura focus si se corupe daca
|
||||
utilizatorul lucreaza in paralel - nu se mai foloseste. Capturile: `PrintWindow` (user32,
|
||||
P/Invoke) pe `Process.MainWindowHandle`, flag `2` = `PW_RENDERFULLCONTENT` (fallback `0` daca
|
||||
iese goala); merge cu fereastra acoperita, NU minimizata. Fereastra se muta OFF-SCREEN
|
||||
(`SetWindowPos`, `HWND_BOTTOM`, x=-4000, `SWP_NOACTIVATE`) la aparitia handle-ului si SE
|
||||
RE-IMPINGE la fiecare pas (VFP se reactiveaza singur la `Show()`/dialoguri). Consolele
|
||||
powershell copil: `-WindowStyle Hidden` (sigur pentru consola, NU pentru GUI VFP ascunsa -
|
||||
`PrintWindow` poate reda gol). Implementat in `vfp_ui_harness.ps1` (Take-Screenshot,
|
||||
Push-Offscreen, Wait-MainWindowHandle) si `_precompile.ps1`.
|
||||
g. **Mock de messagebox**: `FUNCTION amessagebox` care returneaza direct valoarea butonului
|
||||
(6=Da), incarcat cu `SET PROCEDURE ... ADDITIVE` **PRIMUL**, inaintea fisierelor aplicatiei:
|
||||
la nume duplicat de procedura VFP foloseste fisierul cautat PRIMUL (verificat empiric).
|
||||
@@ -83,25 +81,23 @@ i. **Cursorii trebuie sa aiba EXACT indecsii creati de fluxul real** inainte de
|
||||
uneori in cascada la apeluri repetate. Verifica in codul apelant ce indecsi se creeaza si
|
||||
replica-i identic.
|
||||
j. **Mock-urile de date trebuie sa reproduca structura si semantica REALA a sursei** (view
|
||||
Oracle: toate coloanele; relatii intre randuri: toate randurile implicate, nu unul singur cu
|
||||
valori "compuse" manual in test). Un mock incomplet lasa campuri mereu NULL sau ascunde
|
||||
pasul care se testeaza. Cand un flag global activeaza cod suplimentar (ex. `gl406`), acel
|
||||
cod cere mock-uri in plus - verifica ce apeleaza si adauga metodele lipsa din dummy.
|
||||
Cu `gl406=.T.` (SAFT), `GetTaxCodeIdPart`/`GetTaxCode` cer: `goApp.ReadIni`/`WriteIni`
|
||||
(proprietate simpla nu ajunge, clasa `dummyapp` are nevoie de METODE), `goExecutor.oReset`
|
||||
(no-op e suficient), si un cursor `saft_taxtable` real (nu doar mock pe `goExecutor` -
|
||||
`update_jtva_coloane` face `USE saft_taxtable` direct pe alias). Fara ele, simptomul e un
|
||||
dialog nativ Windows "Open" (cauta `saft_taxtable.dbf`) care blocheaza headless la nesfarsit,
|
||||
fara nicio linie noua in log si CPU 0% - vezi `depanare_testare_vfp.md` pentru diagnosticul
|
||||
cu `EnumWindows`/`PrintWindow` pe fereastra ascunsa cand simptomul e "ecran gol, fara eroare".
|
||||
Oracle: toate coloanele; relatii intre randuri: toate randurile implicate, nu una singura cu
|
||||
valori "compuse" manual). Un mock incomplet lasa campuri NULL sau ascunde pasul testat. Cand
|
||||
un flag global activeaza cod suplimentar (ex. `gl406`), acel cod cere mock-uri in plus -
|
||||
verifica ce apeleaza si adauga metodele lipsa din dummy. Cu `gl406=.T.` (SAFT),
|
||||
`GetTaxCodeIdPart`/`GetTaxCode` cer: `goApp.ReadIni`/`WriteIni` (clasa `dummyapp` are nevoie
|
||||
de METODE, nu doar proprietate), `goExecutor.oReset` (no-op e suficient), si cursor
|
||||
`saft_taxtable` real (nu doar mock pe `goExecutor` - `update_jtva_coloane` face
|
||||
`USE saft_taxtable` direct pe alias). Fara ele, simptomul e dialog nativ Windows "Open" (cauta
|
||||
`saft_taxtable.dbf`) care blocheaza headless la nesfarsit, fara linie noua in log si CPU 0% -
|
||||
vezi `depanare_testare_vfp.md` pentru diagnostic cu `EnumWindows`/`PrintWindow`.
|
||||
k. **`LOCATE FOR camp == 'literal'` pe camp `C(n)` padded nu gaseste nimic** (`==` e exact) -
|
||||
foloseste `ALLTRIM(camp) == 'literal'`.
|
||||
l. **`CREATEOBJECT`/`ADDPROPERTY` se comporta gresit apelate DINTR-O PROCEDURA in acest runtime
|
||||
headless** (obiect returnat ca string de 30 spatii; `ADDPROPERTY` da eroare 11). Din
|
||||
programul PRINCIPAL merg. Construieste obiectele-parametru INLINE in main, nu intr-un helper.
|
||||
Cauza confirmata intr-un caz concret: linie de cod prea lunga in ACEEASI metoda de clasa -
|
||||
vezi `depanare_testare_vfp.md` sectiunea 6. Remediul (constructie inline) ramane valabil
|
||||
oricum, indiferent de cauza exacta dintr-un caz punctual.
|
||||
headless** (obiect returnat ca string de 30 spatii; `ADDPROPERTY` da eroare 11). Din programul
|
||||
PRINCIPAL merg. Construieste obiectele-parametru INLINE in main, nu intr-un helper. Cauza
|
||||
confirmata intr-un caz concret: linie de cod prea lunga in ACEEASI metoda de clasa - vezi
|
||||
`depanare_testare_vfp.md` sectiunea 6; remediul (constructie inline) ramane valabil oricum.
|
||||
m. **Fara `SELECT-SQL` pe cursorul legat de grid**: `SELECT ... FROM <cursor> INTO CURSOR` cat
|
||||
timp cursorul e RecordSource-ul unui grid viu poate omori procesul vfp9 silentios (fara
|
||||
eroare catchabila, fara semafor). Foloseste xBase nativ (`COUNT FOR ... TO`, `CALCULATE`,
|
||||
@@ -113,9 +109,9 @@ n. **Wrapper-ul `.ps1` trebuie sa paseze `-SyncDir` daca `.prg`-ul isi seteaza p
|
||||
asteapta un fisier care nu vine). Timeout minim: ~30s x numarul de pasi din `-Steps`
|
||||
(auto-continue per checkpoint din `HarnessWaitContinue`), plus marja de pornire.
|
||||
o. **Formularul resincronizeaza singur dupa o alegere din grid** (`lSyncPending` + `tmrSync`,
|
||||
ex. `do_modifica_explicatie_tva` din `ointroduceri.vcx`): starea de imediat dupa actiune NU e
|
||||
ex. `do_modifica_explicatie_tva` din `ointroduceri.vcx`): starea imediat dupa actiune NU e
|
||||
observabila - `DOEVENTS FORCE` lasa timer-ul sa porneasca, iar resincronizarea rescrie ce
|
||||
tocmai s-a aplicat (la explicatia TVA: randul S revine la familia documentului si randurile T
|
||||
se realiniaza dupa el). Scrie assert-urile pe starea de DUPA resincronizare si alege un efect
|
||||
pe care resincronizarea NU il repara (acolo: `scc`-ul randului T, atins doar cand se schimba
|
||||
explicatia). Altfel testul pica fara sa fie ceva gresit in cod.
|
||||
tocmai s-a aplicat (la explicatia TVA: randul S revine la familia documentului, randurile T se
|
||||
realiniaza dupa el). Scrie assert-urile pe starea de DUPA resincronizare, pe un efect pe care
|
||||
resincronizarea NU il repara (acolo: `scc`-ul randului T, atins doar la schimbarea explicatiei)
|
||||
- altfel testul pica fara sa fie ceva gresit in cod.
|
||||
|
||||
Reference in New Issue
Block a user