Class: Teek::UI::Validator
- Inherits:
-
Object
- Object
- Teek::UI::Validator
- Defined in:
- lib/teek/ui/validator.rb
Overview
"Mixed pack+grid geometry in one container" (the classic Tk-hangs hazard) isn't checked here because, within the pure DSL layout path, it can't happen: Realizer#arrange_children picks exactly one arrangement strategy per container, from that container's own node type, and every container realizes into its own dedicated Tk master
- a guarantee locked down by a realizer test (test_realizer.rb) asserting no master ever receives calls from more than one manager, so a future refactor that shares/flattens frames fails a test instead of shipping the hazard silently.
That guarantee only covers what the DSL itself can construct,
though - it says nothing about the escape hatch. ui.raw,
session.app.command, and a live handle's own app.command calls
are opaque Procs the tree-walking validator can't see inside, so a
raw +pack+/+grid+ call from one of those can still target a master
the DSL already manages - that's the one real, unguardable vector,
not "direct Node/Document manipulation" (which is what the narrower
checks in GridValidator/TabValidator/PaneValidator actually
guard against). If it happens, Tk itself is a synchronous backstop:
it refuses a second geometry manager on an already-managed master
with an immediate, clear Teek::TclError ("cannot use geometry
manager X inside Y") rather than the classic silent hang - but the
DSL has no way to stop the mistake up front, so avoid mixing raw
geometry calls onto a DSL-managed master (see the README's escape
hatch section).
Walks a Document before realize and collects ALL problems, so a broken build can be fixed in one pass instead of a cycle of "run, hit the next cryptic Tcl error, fix, repeat." Headless - no interpreter needed, since it only ever inspects the tree.
Two severities: problems that are "definitely broken" raise (folded
into one ValidationError listing every one found); problems that
are "probably a mistake" warn via Kernel#warn by default, or raise
too under strict: true.
This class runs the checks that span the whole tree or relate arbitrary nodes to each other (dangling event targets, orphans). A specific widget/container's own contract (a grid's children all need cells, a tab's parent must be a ui.tabs, ...) lives in its own WidgetValidators-registered validator instead (see GridValidator/TabValidator/PaneValidator/OverlayValidator), dispatched by node type the same way CommandInterceptors dispatches by widget type. One depth-first walk covers both the document-level checks below and every registered widget validator.
A WidgetType descriptor's own validator: (see WidgetTypes)
needs no separate handling here at all - WidgetTypes.register
forwards it into WidgetValidators directly, so it's dispatched
through the exact same WidgetValidators.for_type call every other
validator already goes through.
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(document, strict: false) ⇒ Validator
constructor
private
A new instance of Validator.
- #validate! ⇒ void
Constructor Details
#initialize(document, strict: false) ⇒ Validator
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of Validator.
73 74 75 76 77 78 79 |
# File 'lib/teek/ui/validator.rb', line 73 def initialize(document, strict: false) @document = document @strict = strict @errors = [] @warnings = [] @reachable = {} end |
Class Method Details
.validate!(document, strict: false) ⇒ Object
68 69 70 |
# File 'lib/teek/ui/validator.rb', line 68 def self.validate!(document, strict: false) new(document, strict: strict).validate! end |
Instance Method Details
#validate! ⇒ void
This method returns an undefined value.
82 83 84 85 86 87 88 |
# File 'lib/teek/ui/validator.rb', line 82 def validate! walk(@document.root, nil) check_orphans @warnings.each { || warn "teek-ui: #{}" } raise ValidationError, @errors.join("\n") if @errors.any? end |