Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/graph/model.red
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,42 @@ find-node-by-id: func [nodes id /local node] [
none
]

; ══════════════════════════════════════════════════
; WIRE GUARD — previene múltiples wires al mismo puerto entrada (QA-018)
; ══════════════════════════════════════════════════
; Regla absoluta #6: NUNCA permitir múltiples wires a un puerto de entrada.
; Esta función verifica si ya existe un wire conectado al mismo nodo+puerto destino.
; Devuelve true si EL wire YA EXISTE (para no añadirlo de nuevo).
wire-exists-to-port?: func [
"Comprueba si ya existe un wire conectado al mismo puerto de entrada"
wires [block!] "Lista de wires a comprobar (model/wires o st/wires)"
to-id [integer!] "ID del nodo destino"
to-port [word!] "Nombre del puerto de entrada"
/local w
][
foreach w wires [
if all [
(w/to-node = to-id)
(w/to-port = to-port)
] [
return true
]
]
false
]

; Añade un wire a una lista solo si el puerto destino no tiene ya uno (QA-018).
; Usar en lugar de `append wires make-wire [...]` en canvas.red y tests.
add-wire: func [
"Añade wire a la lista si el puerto destino aún no tiene uno (regla #6)"
wires [block!] "Lista de wires destino (model/wires o st/wires)"
wire [object!] "Wire creado con make-wire"
][
unless wire-exists-to-port? wires wire/to-node wire/to-port [
append wires wire
]
]

; make-fp-item y fp-value-text viven en src/ui/panel/panel.red (canónico).
; model.red no duplica lógica de Front Panel.

Expand Down
10 changes: 5 additions & 5 deletions src/ui/diagram/canvas.red
Original file line number Diff line number Diff line change
Expand Up @@ -1891,7 +1891,7 @@ render-diagram: func [model canvas-width canvas-height /local canvas-face] [
actual-from-node: model/wire-src-struct/id
]
]
append wire-list make-wire compose [
add-wire wire-list make-wire compose [
from: (actual-from-node)
from-port: (actual-from-port)
to: (hit-nd/id)
Expand Down Expand Up @@ -1953,7 +1953,7 @@ render-diagram: func [model canvas-width canvas-height /local canvas-face] [
_out-t: port-out-type model/wire-src model/wire-port
either _out-t = _sr/data-type [
model/broken-wire: none
append model/wires make-wire compose [
add-wire model/wires make-wire compose [
from: (model/wire-src/id) from-port: (model/wire-port)
to: (_st/id) to-port: (to-word _sr/name)
]
Expand All @@ -1973,7 +1973,7 @@ render-diagram: func [model canvas-width canvas-height /local canvas-face] [
_out-t: port-out-type model/wire-src model/wire-port
either _out-t = _sr/data-type [
model/broken-wire: none
append _st/wires make-wire compose [
add-wire _st/wires make-wire compose [
from: (model/wire-src/id) from-port: (model/wire-port)
to: -2 to-port: (to-word _sr/name)
]
Expand Down Expand Up @@ -2158,7 +2158,7 @@ render-diagram: func [model canvas-width canvas-height /local canvas-face] [
remove-each _w model/wires [
all [_w/to-node = _fst/id _w/to-port = 'count]
]
append model/wires make-wire compose [
add-wire model/wires make-wire compose [
from: (model/wire-src/id) from-port: (model/wire-port)
to: (_fst/id) to-port: "count"
]
Expand Down Expand Up @@ -2347,7 +2347,7 @@ render-diagram: func [model canvas-width canvas-height /local canvas-face] [
actual-from-node: model/wire-src-struct/id
]
]
append wire-list make-wire compose [
add-wire wire-list make-wire compose [
from: (actual-from-node)
from-port: (actual-from-port)
to: (hit-result/1/id)
Expand Down
41 changes: 41 additions & 0 deletions tests/test-model.red
Original file line number Diff line number Diff line change
Expand Up @@ -298,4 +298,45 @@ assert "bundle gen-name bundle_1" (nb1/name = "bundle_1")
assert "bundle gen-name bundle_2" (nb2/name = "bundle_2")
assert "unbundle gen-name unbundle_1" (nu1/name = "unbundle_1")

; ── QA-018 — prohibir múltiples wires al mismo puerto de entrada ─────────

reset-name-counters

; Crear un diagrama con nodos con IDs manuales (make-diagram no tiene next-id)
demo-model: make-diagram "demo"

n1: make-node compose [id: (1) type: 'add x: 100 y: 100]
n2: make-node compose [id: (2) type: 'add x: 250 y: 100]
n3: make-node compose [id: (3) type: 'add x: 400 y: 100]
n4: make-node compose [id: (4) type: 'add x: 550 y: 100]

append demo-model/nodes n1
append demo-model/nodes n2
append demo-model/nodes n3
append demo-model/nodes n4

; Crear 2 wires al mismo puerto de entrada (to-port = 'a)
; El segundo no debe ser añadido (regla absoluta #6 — add-wire lo rechaza)
add-wire demo-model/wires make-wire compose [
from: (1) from-port: 'result to: (2) to-port: 'a
]
add-wire demo-model/wires make-wire compose [
from: (3) from-port: 'result to: (2) to-port: 'a
]

assert "QA-018: solo 1 wire al mismo puerto" (1 = length? demo-model/wires)
assert "QA-018: el primer wire se mantiene" (1 = demo-model/wires/1/from-node)

; Crear 2 wires a puertos distintos del mismo nodo → ambos deben añadirse
add-wire demo-model/wires make-wire compose [
from: (1) from-port: 'result to: (4) to-port: 'a
]
add-wire demo-model/wires make-wire compose [
from: (2) from-port: 'result to: (4) to-port: 'b
]

assert "QA-018: 3 wires en total" (3 = length? demo-model/wires)
assert "QA-018: primer wire a puerto 'a" (1 = demo-model/wires/2/from-node)
assert "QA-018: segundo wire a puerto 'b" (2 = demo-model/wires/3/from-node)

print "--- tests finalizados ---"
Loading