Skip to content

Commit 71a9edf

Browse files
committed
test(showcase): rebuild fixture into a full live demo + labelColumnSpan regression case (v0.1.11)
tests/fixtures/showcase/module.xml grows from a layout/rules test bench into a dual-purpose fixture that also runs for real: module parameters, an audit-trail detail block and a summary block over an aggregate view, a modal reajuste window, more block/item triggers, and demo_schema.sql to seed a real FORMSLANG schema. Compiles clean in Oracle Forms Builder 14c (61/61 units) and round-trips through export/apex-import. Adds a dedicated Frame (FR_IDENTIFICACAO) with a squeezed row of abbreviated-prompt items that reproduces WWV_FLOW_GRID_LAYOUT.LABEL_COLUMN_SPAN_TOO_BIG -- a standing regression case for the labelColumnSpan capping shipped in 0.1.9, since this class of error only ever surfaces at APEX render time. README documents the Forms Builder compile recipe (frmxml2f, frmcmp) and two silent-failure gotchas found doing it: a malformed registry NLS_LANG makes the DB logon fail with ORA-12705 and no module.err, and frmcmp.exe is a GUI-subsystem executable PowerShell won't wait on without Start-Process -Wait. module.fmx/module.err are build output, reproducible from module.xml via that recipe -- gitignored, not committed.
1 parent 79bdce3 commit 71a9edf

10 files changed

Lines changed: 1602 additions & 181 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ formslang-out/
1414
*-out/
1515
out/
1616
*.fmb
17+
*.fmx
18+
*.err
1719
*.mmb
1820
*.olb
1921
*.pll

CHANGELOG.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,28 @@ All notable changes to FormsLang are documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.1.11] — 2026-09-04
9+
10+
### Changed
11+
12+
- **Showcase fixture (`tests/fixtures/showcase/`) rebuilt into a full
13+
live demo**, on top of its existing role as the layout/rules test
14+
bench: module parameters, a third detail block (audit trail) and a
15+
summary block over an aggregate view, two window-modal reajuste flow,
16+
and `demo_schema.sql` to seed a real `FORMSLANG` schema. Compiles
17+
clean in Oracle Forms Builder 14c (61/61 units, no errors) and runs
18+
end to end against Oracle APEX 26.1 after export.
19+
- Added a dedicated Frame (`FR_IDENTIFICACAO`) that reproduces
20+
`WWV_FLOW_GRID_LAYOUT.LABEL_COLUMN_SPAN_TOO_BIG` with a squeezed row of
21+
abbreviated-prompt items, as a standing regression case for the
22+
`labelColumnSpan` capping added in 0.1.9 -- this class of error only
23+
surfaces at APEX render time, never in `apex validate`/`apex import`.
24+
- README documents the full Forms Builder compile recipe (`frmxml2f`,
25+
`frmcmp`) including two silent-failure gotchas: a malformed registry
26+
`NLS_LANG` makes the database logon fail with `ORA-12705` and no
27+
`module.err`, and `frmcmp.exe` is a GUI-subsystem executable that
28+
PowerShell does not wait on unless launched with `Start-Process -Wait`.
29+
830
## [0.1.10] — 2026-09-03
931

1032
### Fixed

desktop/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "formslang-desktop",
33
"private": true,
4-
"version": "0.1.10",
4+
"version": "0.1.11",
55
"scripts": {
66
"tauri": "tauri",
77
"icon:render": "node scripts/render-icon.mjs",

desktop/src-tauri/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

desktop/src-tauri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "formslang-desktop"
3-
version = "0.1.10"
3+
version = "0.1.11"
44
description = "FormsLang desktop shell (B2DEV TECH)"
55
edition = "2021"
66
license = "Apache-2.0"

packaging/formslang-engine.spec

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,4 @@
11
# -*- mode: python ; coding: utf-8 -*-
2-
#
3-
# Before running this spec, reinstall the package non-editably from the repo
4-
# root: `pip install --no-deps --force-reinstall .`. PyInstaller resolves
5-
# `formslang` from whatever is on sys.path, not from this file's location --
6-
# an editable install (`pip install -e .`) breaks static analysis here
7-
# (ModuleNotFoundError: formslang.cli in the frozen exe), and a stale
8-
# non-editable install silently freezes an old release's code with no error
9-
# at build time.
102
from PyInstaller.utils.hooks import collect_data_files
113

124
datas = []

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "formslang"
7-
version = "0.1.10"
7+
version = "0.1.11"
88
description = "Oracle Forms analysis and AI-assisted conversion to Oracle APEX"
99
readme = "README.md"
1010
requires-python = ">=3.10"

tests/fixtures/showcase/README.md

Lines changed: 202 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,45 +3,199 @@
33
`module.xml` -- um módulo Forms2XML 100% sintético (sem dado de cliente,
44
committável; nomeado `module.xml` como o resto de `fixtures/corpus/`,
55
não `*_fmb.xml`, pra não cair na regra do `.gitignore` que barra exports
6-
reais de cliente) desenhado para acionar deliberadamente quase todo
7-
branch relevante de `apexlayout.py` / `apexlang.py` num único módulo, e
8-
servir de exemplo de referência tanto do lado Forms quanto do lado APEX.
6+
reais de cliente) desenhado para dois fins ao mesmo tempo:
7+
8+
1. **Bancada do FormsLang** -- acionar deliberadamente quase todo branch
9+
relevante de `apexlayout.py` / `apexlang.py` (layout geométrico, export
10+
APEXlang) e todas as faixas de veredito de `rules.py` (AUTO / DROP /
11+
ASSISTED / MANUAL / UNKNOWN) num único módulo.
12+
2. **Demo ao vivo** -- converter no Forms Builder 14c, compilar e RODAR de
13+
verdade contra o schema `FORMSLANG` criado por `demo_schema.sql`, pra
14+
mostrar o pipeline inteiro Forms -> `assess` -> APEX com um form que
15+
tem cara de sistema legado de verdade (toolbar, abas, master-detail,
16+
LOVs, auditoria, janela modal, relatório, exportação).
917

1018
Diferente do golden corpus (`fixtures/corpus/`, focado em `rules.py` /
11-
`depgraph.py` -- análise de trigger e grafo de dependência), esta fixture
12-
mira o motor de layout geométrico e o export APEXlang: tipos de item, lado
13-
do prompt, adoção de boilerplate, LOV estática, blocos tabulares/master-
14-
detail, canvases (Content/Toolbar/Tab/Stacked) e itens ocultos.
19+
`depgraph.py` com módulos pequenos), esta fixture é propositalmente
20+
gorda: 5 blocos, 78 itens, 55 triggers, 4 program units, ~500 linhas de
21+
PL/SQL.
1522

1623
## O que o módulo contém
1724

18-
- **Trigger de formulário** (escopo módulo).
19-
- **`BK_PRODUTO`** -- bloco single-record, cabeçalho espalhado por
20-
`CV_MAIN` + `CV_TABS`, com ~24 itens cobrindo:
25+
- **4 `ModuleParameter`** (`P_CATEGORIA_INICIAL`, `P_MODO`, `P_USUARIO`,
26+
`P_DIR_EXPORT`) lidos como `:PARAMETER.X`. `P_MODO='CONSULTA'` trava o
27+
form em somente-leitura no WHEN-NEW-FORM-INSTANCE.
28+
- **14 triggers de formulário**: PRE-FORM (GLOBALs + INSERT direto +
29+
`FORMS_DDL('COMMIT')`), WHEN-NEW-FORM-INSTANCE (título dinâmico,
30+
`CREATE_TIMER`, modo consulta, `EXECUTE_QUERY` inicial), POST-COMMIT,
31+
POST-FORM (`DELETE_TIMER`, `ERASE`), WHEN-TIMER-EXPIRED (relógio na
32+
toolbar), ON-ERROR (`ERROR_CODE`/`DBMS_ERROR_TEXT` -> alerta), ON-MESSAGE
33+
(`MESSAGE_CODE`), KEY-COMMIT / KEY-EXEQRY / KEY-LISTVAL / KEY-CLRFRM /
34+
KEY-EXIT (com `DisplayInKeyboardHelp`), WHEN-WINDOW-CLOSED,
35+
WHEN-TAB-PAGE-CHANGED (`GET_CANVAS_PROPERTY(TOPMOST_TAB_PAGE)`).
36+
- **`BK_PRODUTO`** (`TAB_PRODUTO`) -- bloco single-record, cabeçalho
37+
espalhado por `CV_MAIN` + três abas de `CV_TABS`, cobrindo:
2138
- todo `item_type` mapeado (`Text Item`, `Display Item`, `Check Box`,
22-
`Radio Group`, `List Item`, `Bean Area`/textarea, `Push Button`);
39+
`Radio Group`, `List Item`, `Bean Area`/textarea);
2340
- todo lado de prompt (`Start`→left, `Top`→above, `End`→right,
24-
`Bottom`→below, `Hidden`→sem prompt, itens sem `Prompt`/`Label` mas
25-
com controle→`control`);
41+
`Bottom`→below, `Hidden`→sem prompt, item sem `Prompt`/`Label`);
2642
- boilerplate `Text` adotado como prompt (ao lado e acima) e os casos
2743
que NÃO devem ser adotados (negrito, texto longo demais);
28-
- uma linha propositalmente lotada (8 itens) que reproduz a combinação
29-
inválida `columnSpan`/`labelColumnSpan` (ver "Bug conhecido" abaixo);
44+
- a linha lotada de 8 itens que reproduz o bug `labelColumnSpan`
45+
(ver "Bug conhecido" abaixo);
3046
- itens ocultos via `Visible="false"` **e** via ausência de
31-
`CanvasName` (as duas rotas para `layout.hidden`).
32-
- **`BK_ITENS`** -- bloco tabular master-detail (via `Relation`) em
33-
`CV_TABS`/`TAB_ITENS`.
34-
- **`CONTROL`** -- bloco não-database com botões, dividido entre o
35-
canvas toolbar (`CV_TOOLBAR`, Horizontal Toolbar) e um canvas
36-
stacked-invisible (`CV_CONFIRMA`, vira inline-dialog).
37-
- **`ProgramUnit`**, **`RecordGroup`+`LOV`** estática (completude do lado
38-
Forms; o motor de layout não usa RecordGroup/LOV nomeada -- só gera LOV
39-
estática a partir de `List Item`/`Radio Group` com choices fixos),
40-
**`VisualAttribute`**, **`Relation`**, **`Alert`**, 4 `Canvas` (ordem de
47+
`CanvasName`;
48+
- propriedades Forms que o parser ainda não lê mas o compilador exige
49+
ou usa: `PrimaryKey`, `FormatMask`, `InitializeValue` (Radio Group e
50+
Check Box precisam -- FRM-30188 / FRM-30174 sem isso),
51+
`CheckedValue`/`UncheckedValue`, `ValidateFromList`, `MultiLine` +
52+
`WrapStyle`, `Tooltip`/`Hint`, `LowestAllowedValue`/`HighestAllowedValue`;
53+
- triggers de bloco PRE-QUERY (`DEFAULT_WHERE` dinâmico), POST-QUERY
54+
(lookups + `SET_ITEM_INSTANCE_PROPERTY` com visual attribute por
55+
registro), PRE-INSERT / PRE-UPDATE / PRE-DELETE, WHEN-VALIDATE-RECORD,
56+
WHEN-CREATE-RECORD, WHEN-NEW-RECORD-INSTANCE; triggers de item
57+
WHEN-VALIDATE-ITEM (um deles chama `PKG_PRODUTO.F_VALIDA_EAN13` no
58+
banco), WHEN-LIST-CHANGED, WHEN-RADIO-CHANGED, WHEN-CHECKBOX-CHANGED,
59+
WHEN-MOUSE-DOUBLECLICK (`LIST_VALUES` e `SHOW_EDITOR`);
60+
- duas `Relation` (filhas do bloco mestre, como o forms.xsd exige):
61+
`REL_ITENS` (Isolated, exclusão dos filhos feita à mão no PRE-DELETE)
62+
e `REL_AUDIT` (Deferred + AutoQuery).
63+
- **`BK_ITENS`** (`TAB_PRODUTO_ITEM`) -- bloco tabular master-detail, 5
64+
linhas, scrollbar própria, `SEQ_ITEM` por MAX+1 no PRE-INSERT e um item
65+
de fórmula (`VL_TOTAL_LINHA`, `CalculateMode="Formula"`).
66+
- **`BK_AUDIT`** (`TAB_PRODUTO_AUDIT`) -- detalhe somente-leitura da
67+
trilha gravada pelo trigger de banco; `DataType="Datetime"`, filtro
68+
extra vindo de `CONTROL.PC_TP_OPERACAO` (LOV estática) no PRE-QUERY.
69+
- **`BK_RESUMO`** (`VW_PRODUTO_RESUMO`) -- bloco sobre view agregada (sem
70+
ROWID: `KeyMode="Non-Updateable"` + `PrimaryKey`), duplo clique na
71+
categoria faz drill-down no mestre.
72+
- **`CONTROL`** -- bloco não-database: toolbar de 2 linhas (Salvar,
73+
Cancelar, Excluir, Consultar, Novo, Duplicar, Reajuste, Relatório,
74+
Exportar, check box "Somente ativos", Site, Calculadora, Ajuda, relógio),
75+
diálogo inline em canvas stacked (`CV_CONFIRMA`), janela modal de
76+
reajuste (`CV_REAJUSTE`/`WIN_REAJUSTE`, chama procedure do banco com
77+
parâmetro OUT) e botões dentro das abas.
78+
- **4 `ProgramUnit`**: Procedure, Function e Package Spec + Body
79+
(`PKG_UTIL`).
80+
- **3 `RecordGroup`** (Query simples, Query com WHERE, `Static` com
81+
`RecordGroupColumnRow`) e **4 `LOV`** -- `RG_CATEGORIA` é compartilhado
82+
por duas LOVs com `ReturnItem` diferentes.
83+
- **3 `VisualAttribute`**, **4 `Alert`** (Note / Stop / Caution com 3
84+
botões), **1 `Editor`** (não existe atributo Item→Editor no forms.xsd;
85+
é aberto por `SHOW_EDITOR` num trigger), **1 `Report`** (Oracle Reports,
86+
só compila -- não há report server na demo).
87+
- **5 `Canvas`** (`CV_TOOLBAR` Horizontal Toolbar, `CV_MAIN` Content com
88+
Frames/Text/Rectangle, `CV_TABS` Tab com 5 páginas, `CV_CONFIRMA`
89+
Stacked invisível, `CV_REAJUSTE` Content da segunda janela -- a ordem de
4190
declaração é significativa: `CV_TOOLBAR` antes de `CV_MAIN` para o
42-
hosting do toolbar funcionar) e 1 `Window`.
91+
hosting do toolbar funcionar) e **2 `Window`** (Document + Dialog Modal).
92+
93+
### Cobertura de vereditos (`rules.py`)
94+
95+
`formslang assess tests/fixtures/showcase/module.xml` hoje reporta
96+
Triggers `AUTO=13 DROP=1 ASSISTED=38 MANUAL=2 UNKNOWN=1` e Built-ins
97+
`AUTO=60 DROP=4 ASSISTED=55 MANUAL=14`, tier REWRITE. Os MANUAL são
98+
propositais e cada um representa um padrão legado real:
99+
`CREATE_TIMER`/`DELETE_TIMER`, `FORMS_DDL`, `HOST('calc.exe')`,
100+
`RUN_REPORT_OBJECT`, `TEXT_IO`. As chamadas fora do catálogo
101+
(`PKG_PRODUTO.*`, `PKG_UTIL.*`, `MESSAGE_CODE`, `GET_CANVAS_PROPERTY`,
102+
`SET_ITEM_INSTANCE_PROPERTY`, `ERASE`, `SHOW_EDITOR`) caem em
103+
`unknown_calls` de propósito -- é o que o assess deve apontar como
104+
"regra já no banco" ou "dívida de catálogo".
105+
106+
## Rodando de verdade no Forms Builder
107+
108+
### 1. Schema de demo (`demo_schema.sql`)
109+
110+
Cria, de forma idempotente (dropa e recria), no schema `FORMSLANG`:
111+
`TAB_CATEGORIA`, `TAB_FORNECEDOR`, `TAB_PRODUTO` (+ `TAB_PRODUTO_SEQ`),
112+
`TAB_PRODUTO_ITEM`, `TAB_PRODUTO_AUDIT`, `TAB_FORM_ACESSO`, a view
113+
`VW_PRODUTO_RESUMO`, o package `PKG_PRODUTO` (`F_VALIDA_EAN13`,
114+
`F_TOTAL_ITENS`, `F_DS_STATUS`, `P_APLICA_REAJUSTE`) e o trigger de
115+
auditoria `TRG_TAB_PRODUTO_AUDIT`. Semeia 4 categorias, 4 fornecedores, 6
116+
produtos com EAN-13 válidos, 6 itens e 9 linhas de auditoria (3 delas
117+
geradas por UPDATEs de exemplo: reajuste de preço, inativação, bloqueio).
118+
Não é lido pelo parser nem pelos testes.
119+
120+
```powershell
121+
# SQLcl thin, sem tnsnames (no Git Bash exporte MSYS_NO_PATHCONV=1 antes,
122+
# senão o /nolog vira caminho Windows e o SQLcl imprime o usage)
123+
printf '%s\n' 'connect FORMSLANG/<senha>@localhost:1521/FREEPDB1' `
124+
'@tests\fixtures\showcase\demo_schema.sql' 'exit' | sql -S -thin /nolog
125+
```
126+
127+
O script termina com SELECTs de conferência (`user_objects` tudo VALID,
128+
contagens por tabela, `user_errors` vazio).
129+
130+
### 2. Converter e compilar
43131

44-
## Como validar
132+
Pelo Forms Builder: **File > Convert...** (XML to Forms Module, "Overwrite
133+
existing" marcado) apontando pro `module.xml`; abrir o `.fmb`, conectar
134+
como `FORMSLANG` e **Compile All** (Ctrl+Shift+K); depois **Run Form**.
135+
136+
Por linha de comando (Forms 14.1.2, Home `C:\Oracle\FR1412` -- o antigo
137+
`C:\Oracle\Middleware` foi removido em 2026-09-04, era um Home legado
138+
paralelo):
139+
140+
```powershell
141+
# XML -> FMB (não precisa de banco; avisa que não validou os Record Groups).
142+
# frmxml2f.bat só acha java/jars com ORACLE_HOME setado.
143+
$env:ORACLE_HOME = "C:\Oracle\FR1412"
144+
C:\Oracle\FR1412\forms\templates\scripts\frmxml2f.bat module.xml OVERWRITE=YES
145+
146+
# FMB -> FMX (precisa de banco). NLS_LANG explícito é obrigatório numa
147+
# instalação cujo registro tem NLS_LANG malformado: sem isso o logon
148+
# falha com ORA-12705 SILENCIOSO (exit 1, sem module.err). Nunca passe
149+
# help=yes -- abre um diálogo e trava o batch.
150+
# frmcmp.exe é executável GUI (PE subsystem 2): o PowerShell NÃO espera
151+
# ele terminar quando chamado com `&` -- volta em ~6ms, $LASTEXITCODE
152+
# vazio, e module.fmx/module.err só aparecem uns 20s depois. Use
153+
# Start-Process -Wait (ou pipe). Não precisa de ORACLE_HOME nem de
154+
# ORACLE_HOME\bin no PATH (testado).
155+
$env:NLS_LANG = "AMERICAN_AMERICA.WE8MSWIN1252"
156+
$env:TNS_ADMIN = "C:\Oracle\FR1412\user_projects\domains\forms_domain\config\fmwconfig"
157+
$p = Start-Process -FilePath "C:\Oracle\FR1412\bin\frmcmp.exe" `
158+
-ArgumentList "module=module.fmb", "userid=FORMSLANG/<senha>@FREEPDB1", `
159+
"logon=yes", "batch=yes", "compile_all=yes", "window_state=minimize" `
160+
-WorkingDirectory (Get-Location) -NoNewWindow -Wait -PassThru
161+
$p.ExitCode # 0
162+
Get-Content module.err # 61 unidades, todas "No compilation errors."
163+
```
164+
165+
### 3. Roteiro de teste manual (o que a demo mostra)
166+
167+
1. Abrir: título da janela ganha o usuário, toolbar mostra o relógio, o
168+
bloco já vem consultado (6 produtos, ordenado por nome). Uma linha em
169+
`TAB_FORM_ACESSO` foi gravada pelo PRE-FORM.
170+
2. Navegar (Page Down): "Parafusadeira" aparece com o nome em vermelho
171+
(`VA_BLOQUEADO`, `TP_STATUS='BLOQUEADO'`). Botão Excluir desabilita em
172+
registro novo (WHEN-NEW-RECORD-INSTANCE).
173+
3. Aba **Itens**: Furadeira totaliza `134,90`, Notebook `209,80`, Camiseta e
174+
Parafusadeira `0,00`; a coluna Total de cada linha é a fórmula.
175+
4. Aba **Comercial**: fornecedor via LOV (F9 / duplo clique) -- só
176+
homologados aparecem; "Textil Delta" não. Datas/usuário de alteração
177+
são somente-leitura.
178+
5. Aba **Auditoria**: histórico do produto; filtrar por `UPDATE` com a LOV
179+
estática + botão Filtrar.
180+
6. Aba **Resumo**: 4 categorias com contagens e valor de estoque; duplo
181+
clique numa categoria reconsulta a tela principal filtrada.
182+
7. Toolbar **Reajuste**: abre a janela modal, escolher categoria (LOV que
183+
reusa `RG_CATEGORIA`), informar 10, Aplicar -> alerta com a quantidade;
184+
a aba Auditoria ganha linhas "Preco alterado de X para Y".
185+
8. **Novo** / **Duplicar** / **Salvar** (F10): defaults do WHEN-CREATE-RECORD;
186+
`PK_ID` vem da sequence no PRE-INSERT; `CD_BARRA` inválido é barrado
187+
pelo `F_VALIDA_EAN13` do banco; peso líquido > bruto é barrado pelo
188+
WHEN-VALIDATE-RECORD.
189+
9. **Excluir**: diálogo inline (canvas stacked) -> Confirmar apaga os itens
190+
(PRE-DELETE) e o produto, alerta de sucesso.
191+
10. **Exportar**: gera `produto_<id>.csv` em `P_DIR_EXPORT` (TEXT_IO).
192+
**Site** abre b2dev.tech, **Calculadora** chama `HOST`, **Ajuda** mostra
193+
usuário e nº de consultas da sessão (`:GLOBAL`).
194+
11. Sair (Ctrl+Q / X) com alteração pendente: alerta de 3 botões.
195+
12. **Relatório** só funciona com um Oracle Reports server configurado
196+
(`rep_server`); sem ele, mostra o status devolvido.
197+
198+
## Como validar (lado FormsLang)
45199

46200
Não existe ainda um teste automatizado pytest para esta fixture (é usada
47201
via script ad hoc). Rotina manual:
@@ -52,6 +206,7 @@ from formslang.apexlayout import build_layout
52206
from formslang.apexlang import export_apexlang
53207
from formslang.store import Store
54208
from formslang.convert import build_tasks
209+
from formslang.apeximport import run_import
55210

56211
module = parse_xml("tests/fixtures/showcase/module.xml")
57212
layout = build_layout(module, 1) # inspeciona a árvore de regiões
@@ -61,11 +216,28 @@ store.init_session(module.name, "tests/fixtures/showcase/module.xml")
61216
store.add_tasks(build_tasks(module))
62217
result = export_apexlang(store, module, "/tmp/out",
63218
{"app_id": 101, "name": "DEMO_ALL_ELEMENTS", "alias": "demo-all-elements"})
219+
run_import(result.zip_path, connect_string="localhost:1521/FREEPDB1",
220+
username="FORMSLANG", password="...", validate_only=True) # apex validate
64221
```
65222

66-
Depois, `apex validate` (SQLcl) no zip exportado confirma que o APEXlang
67-
gerado é sintaticamente válido -- mas **não** pega erros de renderização
68-
de página (ver abaixo).
223+
Estado atual: 22 regiões, 78 itens mapeados, 0 pulados, 2 LOVs estáticas
224+
(`TP_UNIDADE`, `TP_STATUS`), `apex validate` "Validation successful."
225+
Também vale conferir o XML contra o `forms.xsd` oficial (lxml
226+
`XMLSchema.validate`) -- nenhum atributo aqui foi inventado; todos
227+
existem no xsd do Forms 14c.
228+
229+
### Limitações conhecidas do mapeamento (de propósito, pra demo ser honesta)
230+
231+
- `MultiLine`/`WrapStyle` de `OBS_GERAL` não são lidos pelo parser -- vira
232+
`textField` no APEX; só `Bean Area` vira `textarea` (convenção
233+
documentada em `test_apexlang.py`).
234+
- `WIN_REAJUSTE` (janela modal) vira uma região comum na mesma página, não
235+
uma página modal separada.
236+
- `CalculateMode="Formula"` de `VL_TOTAL_LINHA` vira `Display Item` sem
237+
cálculo -- a fórmula fica registrada como dívida no assess.
238+
- `Report`, `Editor`, `ModuleParameter` e os `RecordGroup`/`LOV` nomeados
239+
são contados pelo parser, mas o motor de layout não os consome (a LOV
240+
do APEX é gerada só a partir de `List Item`/`Radio Group`).
69241

70242
## Bug conhecido, reproduzido aqui de propósito -- CORRIGIDO
71243

0 commit comments

Comments
 (0)