Files
comun/utile/Teste/mock_cauta_alfa_dialog.prg
Marius Mutu 53d9f1c64a Achizitie import unificata (ROAGEST): ointroduceri, teste UI, documentatie
- import_nota / import_adauga_factura: flux unificat note contabile + articole,
  sincronizare automata, total factura automat, TVA impartit pe conturile
  creditoare ale notelor (rundele 1-31)
- runda 32: totalurile import_nota pe _label/_textbox din _baza.vcx (Arial 10),
  fara containerele clb_tx_simplu si fara bifa "Recalculeaza TVA" (recalcul
  mereu automat); "Sincronizeaza facturile secundare" mutata sub butoane
- utile/Teste: harness UI VFP headless (vfp_ui_harness.ps1, ui_harness.prg,
  precompilare, mock-uri) in radacina; suitele e2e pentru achizitia din import
  grupate in utile/Teste/achizitie_import/
- docs: flux editare text vcx/scx, testare-ui-vfp si testare-vfp-mcp (mutate
  din ROAGEST, general valabile), inventar comun, orchestrare subagenti,
  conventie GO recno, depanare testare VFP

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019DGibQKa5uK4P2TNSFFQNh
2026-07-20 00:50:18 +03:00

172 lines
7.8 KiB
Plaintext

* mock_cauta_alfa_dialog.prg - inlocuieste DOAR PROCEDURE cauta_alfa (COMUN\programe\cauta_alfa.prg,
* linia 16), NU cauta_nom_articole/XML2ListaIDDescriere/do_adauga_articol - acelea raman REALE,
* neatinse. Se incarca PRIMUL (inaintea "SET PROCEDURE TO cauta_alfa ADDITIVE") - la nume duplicat
* de procedura VFP foloseste fisierul incarcat PRIMUL (vezi docs/testare-ui-vfp.md capcana j).
*
* De ce: cauta_alfa() reala populeaza cursorul din Oracle prin gencursor->ca_baza.afisare(), care
* foloseste This.CursorFill() (CursorAdapter/conexiune reala) - nu goExecutor, deci nu poate fi
* mock-uit ca restul infrastructurii (vezi COMUN\clase\decabaza.vc2:36-99). Acest shadow inlocuieste
* DOAR sursa de date (Oracle -> cursor mock pre-populat de test) si bucla de asteptare modala
* (WindowType=1, Show() blocheaza pana la Release -> WindowType=0 + actiuni conduse programatic
* dupa Show(), vezi docs/testare-ui-vfp.md capcana g). Formularul e clasa REALA cauta_alfa_form
* (COMUN\clase\cauta_alfa_forms.vcx), metodele apelate (do_alege, do_termin, do_renunt) sunt cele
* REALE, neschimbate - doar interactiunea utilizatorului e simulata in loc de bucla de evenimente.
*
* IMPORTANT (capcana l, docs/testare-ui-vfp.md): CREATEOBJECT apelat DINTR-O PROCEDURA (nu din
* programul principal) intoarce un obiect stricat in acest runtime headless (verificat empiric -
* "OFORM_CAUTARE is not an object" la prima folosire). De aceea formularele NU se creeaza aici -
* testul principal le PRE-CONSTRUIESTE inline (goDlgA/goDlgB/goDlgC) INAINTE sa apeleze
* do_adauga_articol, iar acest shadow doar SELECTEAZA obiectul potrivit dupa gcTestScenariu si ii
* apeleaza metodele reale (asta e simpla dispecerizare de metoda, nu CREATEOBJECT - functioneaza
* din procedura fara probleme).
*
* Control test (setate de testul principal INAINTE de fiecare apel):
* goDlgA / goDlgB / goDlgC - formularele REALE pre-construite (vezi test_picker_real_212.prg)
* gcTestScenariu - 'A' (marcheaza BULDOEXCAVATOR + OK), 'B' (nimic marcat + OK),
* 'C' (dublu-click pe denumire), altfel Cancel
* Rezultat expus (citit de testul principal dupa apel):
* gcTestGnButon, gcTestXML, gcTestLenXML, gcTestCAles, gcTestPcAles, gcTestRandiuriMarcate
Procedure cauta_alfa
Parameters tcselect,tcfiltru,tcschema,tcorder,tccoloana,tcTitlu,tcTitluColoane, ;
tcNume_Proc,tl_AllInList,tcFiltruOriginal,tcPrimaColoana, tnPornire, tnTipReturn, ;
tcIdColumn, tlDesktop, tcGroup, tcGridDynamicBackColor, tcGridToolTip, tlModParam, tcStringCriterii, ;
tcProceduraVerifica, tcProceduraCopiaza,tcLocate
LOCAL lcCursor, lcCursorXML, lcCAlesDupaMarcare
LOCAL oForm_cautare, oReturnScattObj
Private pcAles
pcAles = ""
gcTestRandiuriMarcate = 0
IF USED('crsReturnAlfa')
USE IN ('crsReturnAlfa')
ENDIF
*-- === selecteaza obiectul PRE-CONSTRUIT (vezi capcana l mai sus - fara CREATEOBJECT aici) ===
DO CASE
CASE gcTestScenariu == 'A'
oForm_cautare = goDlgA
CASE gcTestScenariu == 'B'
oForm_cautare = goDlgB
CASE gcTestScenariu == 'C'
oForm_cautare = goDlgC
OTHERWISE
oForm_cautare = goDlgA
ENDCASE
lcCursor = oForm_cautare.crs_cursor
*-- pcAles trebuie sa reflecte marcajul curent INAINTE de a incepe (formularul e deja afisat,
*-- creat in main); il sincronizez manual cu cAles-ul formularului la pornire, exact cum face
*-- BINDEVENT(Thisform,"lAles",...) + do_alege() in fluxul real (do_alege scrie in AMBELE,
*-- Thisform.cAles si pcAles - vezi cauta_alfa_forms.vc2:405-418).
pcAles = oForm_cautare.cAles
*-- === FAZA 1: marcare - simuleaza interactiunea utilizatorului cu formularul REAL ===
*-- IMPORTANT: NU se atinge oForm_cautare dupa do_termin()/do_renunt() - acele metode fac
*-- this.Release, care DISTRUGE efectiv formularul VFP (verificat empiric: accesarea unei
*-- proprietati dupa Release da eroare 1924 "is not an object", chiar daca alta variabila
*-- (goDlgA) inca "tine" referinta) - de-aia cauta_alfa.prg REAL insusi nu mai citeste nimic
*-- de pe oForm_cautare dupa .Show() decat prin pcAles/gnButon (variabile libere, nu proprietati
*-- de obiect). Orice diagnostic despre cAles trebuie capturat AICI, inainte de faza 2.
DO CASE
CASE gcTestScenariu == 'A'
*-- marcheaza randul BULDOEXCAVATOR prin mecanismul real (echivalentul click pe denumire /
*-- SPACE): do_alege() citeste RECNO() curent al cursorului si toggle-uie cAles la acea pozitie.
SELECT (lcCursor)
LOCATE FOR ALLTRIM(denumire) == 'BULDOEXCAVATOR'
IF FOUND()
oForm_cautare.do_alege()
ENDIF
lcCAlesDupaMarcare = oForm_cautare.cAles
IF TYPE('gcUILog') = 'C'
DO HarnessStep WITH 1, 'scenariul A: BULDOEXCAVATOR marcat (Thisform.cAles=[' + lcCAlesDupaMarcare + ']), inainte de OK real'
ENDIF
CASE gcTestScenariu == 'B'
*-- nimic marcat
SELECT (lcCursor)
GO TOP
lcCAlesDupaMarcare = oForm_cautare.cAles
CASE gcTestScenariu == 'C'
*-- "dublu-click pe denumire": in modul multi-select (lAles=.T., cazul cauta_nom_articole),
*-- BindEvent(dblClick->do_termin) NU se armeaza (cauta_alfa_forms.vc2:652 "If !Thisform.lales"),
*-- deci dublu-click = 2x acelasi Click -> do_alege() de 2 ori (marcheaza, apoi demarcheaza) -
*-- NU exista submit rapid pe dublu-click in acest dialog. Simulez exact gestul (2 click-uri pe
*-- Column1.Text1, handler-ul REAL) si documentez ca cursorul ramane nemarcat.
SELECT (lcCursor)
LOCATE FOR ALLTRIM(denumire) == 'BULDOEXCAVATOR'
IF FOUND()
oForm_cautare._GRID1.Column1.Text1.Click()
oForm_cautare._GRID1.Column1.Text1.Click()
ENDIF
lcCAlesDupaMarcare = oForm_cautare.cAles
IF TYPE('gcUILog') = 'C'
DO HarnessLog WITH 'scenariul C: dupa 2x Click (dublu-click simulat) cAles=[' + lcCAlesDupaMarcare + '] (astept ramas needecis, fara submit automat)'
ENDIF
OTHERWISE
lcCAlesDupaMarcare = oForm_cautare.cAles
ENDCASE
*-- diagnostic cerut de team lead: pcAles (variabila PRIVATE folosita mai jos in filtrul WHERE al
*-- XML-ului) vs Thisform.cAles (marcajul vizual/albastrit vazut de Marius) - trebuie sa fie
*-- SINCRONE la acest punct, INAINTE de faza 2 (inchidere), pentru ca acolo se pierde accesul.
gcTestPcAlesInainte = pcAles
gcTestCAlesInainte = lcCAlesDupaMarcare
*-- === FAZA 2: inchidere - butonul OK/Cancel REAL (this.Release -> oForm_cautare devine inert) ===
DO CASE
CASE gcTestScenariu == 'A' OR gcTestScenariu == 'B' OR gcTestScenariu == 'C'
oForm_cautare.do_termin() && butonul OK REAL (_frm_base.do_termin: gnButon=1, Release)
OTHERWISE
oForm_cautare.do_renunt()
ENDCASE
DOEVENTS FORCE
*-- === de aici incolo: cod IDENTIC cu cauta_alfa.prg original (COMUN\programe\cauta_alfa.prg,
*-- liniile 218-249) - aceeasi conditie, acelasi filtru (pcAles), acelasi CURSORTOXML. NU se mai
*-- atinge oForm_cautare (a fost Release-uit de do_termin/do_renunt mai sus). ===
lcCursorXML = ""
SELECT (lcCursor)
IF gnButon=1
Do Case
Case tnTipReturn = 0
Scatter Name oReturnScattObj Memo
Otherwise
Select * From (lcCursor) With (Buffering = .T.) Where Substr(pcAles,Recno(),1) = 'X' ;
INTO Cursor crsReturnAlfa
Cursortoxml("crsReturnAlfa", "lcCursorXML", 2, 0+2+8, 0, "1")
gcTestRandiuriMarcate = RECCOUNT('crsReturnAlfa')
Use In crsReturnAlfa
Endcase
Else
Do Case
Case tnTipReturn = 0
Scatter Name oReturnScattObj Blank
Otherwise
lcCursorXML = ""
Endcase
Endif
*-- expus pentru diagnostic in testul principal (cAles luat din snapshot-ul de dinainte de
*-- Release - vezi FAZA 1 - NU de pe oForm_cautare, care e deja inert dupa do_termin/do_renunt)
gcTestGnButon = gnButon
gcTestXML = lcCursorXML
gcTestLenXML = LEN(m.lcCursorXML)
gcTestCAles = lcCAlesDupaMarcare
gcTestPcAles = pcAles
*-- NU dau Release aici (obiectul e deja Release-uit de do_termin/do_renunt mai sus)
Use In (lcCursor)
Do Case
Case tnTipReturn = 0
Return oReturnScattObj
Otherwise
Return lcCursorXML
Endcase
Endproc && cauta_alfa (shadow test)