• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

asciimoth / pasta / 26626415405

29 May 2026 08:18AM UTC coverage: 77.855% (-0.3%) from 78.117%
26626415405

push

github

asciimoth
fix(std): fix formular menu handling by some nodes

20 of 72 new or added lines in 12 files covered. (27.78%)

1 existing line in 1 file now uncovered.

5467 of 7022 relevant lines covered (77.86%)

323.08 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.05
/pasta/std/node_bool.go
1
package std
2

3
import (
4
        "github.com/asciimoth/configer/configer"
5
        "github.com/asciimoth/formular"
6
        "github.com/asciimoth/pasta/pasta"
7
)
8

9
type boolNode struct {
10
        pasta.BasicNode
11

12
        op     string
13
        value  bool
14
        inputs map[uint64]bool
15

16
        w     *pasta.Workspace
17
        id    uint64
18
        out   uint64
19
        lefts []uint64
20
}
21

22
func newBoolConstantNode(value bool) *boolNode {
12✔
23
        return &boolNode{op: "const", value: value, inputs: map[uint64]bool{}}
12✔
24
}
12✔
25

26
func newBoolNode(op string) *boolNode {
7✔
27
        return &boolNode{op: op, inputs: map[uint64]bool{}}
7✔
28
}
7✔
29

30
func (n *boolNode) OnInit(w *pasta.Workspace, _ pasta.Logger, id uint64, _ string, restored *pasta.NodeInitData, _, _, _, _ bool) error {
19✔
31
        n.w = w
19✔
32
        n.id = id
19✔
33
        if restored != nil {
38✔
34
                if len(restored.RightPorts) > 0 {
38✔
35
                        n.out = restored.RightPorts[0]
19✔
36
                }
19✔
37
                n.lefts = append([]uint64{}, restored.LeftPorts...)
19✔
38
        }
39
        if err := n.w.SetNodePrimary(n.id, TypeBool); err != nil {
19✔
40
                return err
×
41
        }
×
42
        n.recalculate(false)
19✔
43
        if err := n.updateLabel(); err != nil {
19✔
44
                return err
×
45
        }
×
46
        n.sendMenuSnapshot()
19✔
47
        return nil
19✔
48
}
49

50
func (n *boolNode) OnReady() error {
19✔
51
        n.requestAll()
19✔
52
        n.sendAll()
19✔
53
        return nil
19✔
54
}
19✔
55

56
func (n *boolNode) PreLinkAdd(port uint64, linkType, portDirection string) error {
27✔
57
        if linkType != TypeBool {
27✔
NEW
58
                return pasta.LinkTypeErr(linkType)
×
59
        }
×
60
        if portDirection == "left" {
40✔
61
                snapshot, ok := n.w.PortSnapshot(port)
13✔
62
                if ok && len(snapshot.Links) > 0 {
14✔
63
                        return pasta.ErrLinkDup
1✔
64
                }
1✔
65
        }
66
        return nil
26✔
67
}
68

69
func (n *boolNode) OnLinkAdd(link, port uint64, _ string, portDirection string) error {
26✔
70
        if portDirection == "left" {
38✔
71
                n.requestLink(link, port)
12✔
72
                return nil
12✔
73
        }
12✔
74
        if port == n.out {
28✔
75
                n.sendToLink(link)
14✔
76
        }
14✔
77
        return nil
14✔
78
}
79

80
func (n *boolNode) OnLinkRemoved(_ uint64, port uint64, _ string, portDirection string) error {
1✔
81
        if portDirection == "left" {
1✔
82
                delete(n.inputs, port)
×
83
                n.recalculate(true)
×
84
        }
×
85
        return nil
1✔
86
}
87

88
func (n *boolNode) OnEvent(event pasta.Event, linkType string, _ []string, receiverPortDirection string) error {
55✔
89
        if linkType != TypeBool {
55✔
90
                return nil
×
91
        }
×
92
        if receiverPortDirection == "right" {
75✔
93
                if isBoolRequest(event.Payload) {
40✔
94
                        n.w.SendEvent(pasta.Event{SenderNode: n.id, SenderPort: n.out, ReceiverNode: event.SenderNode, ReceiverPort: event.SenderPort, Payload: n.value})
20✔
95
                }
20✔
96
                return nil
20✔
97
        }
98
        value, ok := event.Payload.(bool)
35✔
99
        if !ok {
35✔
100
                return nil
×
101
        }
×
102
        n.inputs[event.ReceiverPort] = value
35✔
103
        n.recalculate(true)
35✔
104
        return nil
35✔
105
}
106

107
func (n *boolNode) OnSave(cfg configer.Config) error {
7✔
108
        if n.op != "const" {
10✔
109
                return nil
3✔
110
        }
3✔
111
        if err := pasta.DeleteNodeOwnedConfigKeys(cfg); err != nil {
4✔
112
                return err
×
113
        }
×
114
        return cfg.Set(configer.Path{"value"}, n.value)
4✔
115
}
116

117
func (n *boolNode) recalculate(broadcast bool) {
54✔
118
        old := n.value
54✔
119
        switch n.op {
54✔
120
        case "and":
20✔
121
                n.value = n.input(0) && n.input(1)
20✔
122
        case "or":
14✔
123
                n.value = n.input(0) || n.input(1)
14✔
124
        case "not":
8✔
125
                n.value = !n.input(0)
8✔
126
        }
127
        _ = n.updateLabel()
54✔
128
        n.sendMenuBlock()
54✔
129
        if broadcast && old != n.value {
60✔
130
                n.sendAll()
6✔
131
        }
6✔
132
}
133

134
func (n *boolNode) input(index int) bool {
60✔
135
        if index >= len(n.lefts) {
60✔
136
                return false
×
137
        }
×
138
        return n.inputs[n.lefts[index]]
60✔
139
}
140

141
func (n *boolNode) requestAll() {
19✔
142
        for _, port := range n.lefts {
31✔
143
                snapshot, ok := n.w.PortSnapshot(port)
12✔
144
                if !ok {
12✔
145
                        continue
×
146
                }
147
                for _, link := range snapshot.Links {
17✔
148
                        n.requestLink(link, port)
5✔
149
                }
5✔
150
        }
151
}
152

153
func (n *boolNode) requestLink(link, port uint64) {
17✔
154
        snapshot, ok := n.w.LinkSnapshot(link)
17✔
155
        if !ok {
17✔
156
                return
×
157
        }
×
158
        receiverNode, receiverPort := otherEndpoint(snapshot, port)
17✔
159
        n.w.SendEvent(pasta.Event{SenderNode: n.id, SenderPort: port, ReceiverNode: receiverNode, ReceiverPort: receiverPort, Payload: RequestValue{}})
17✔
160
}
161

162
func (n *boolNode) sendAll() {
25✔
163
        port, ok := n.w.PortSnapshot(n.out)
25✔
164
        if !ok {
25✔
165
                return
×
166
        }
×
167
        for _, link := range port.Links {
30✔
168
                n.sendToLink(link)
5✔
169
        }
5✔
170
}
171

172
func (n *boolNode) sendToLink(link uint64) {
19✔
173
        snapshot, ok := n.w.LinkSnapshot(link)
19✔
174
        if !ok {
19✔
175
                return
×
176
        }
×
177
        receiverNode, receiverPort := otherEndpoint(snapshot, n.out)
19✔
178
        n.w.SendEvent(pasta.Event{SenderNode: n.id, SenderPort: n.out, ReceiverNode: receiverNode, ReceiverPort: receiverPort, Payload: n.value})
19✔
179
}
180

181
func (n *boolNode) updateLabel() error {
73✔
182
        return n.w.SetNodeLabel(n.id, boolLabel(n.value))
73✔
183
}
73✔
184

185
func (n *boolNode) sendMenuSnapshot() {
19✔
186
        n.w.SendNodeMenuMsg(n.id, formular.MenuSnapshotMessage{
19✔
187
                MessageBase: formular.MessageBase{Type: formular.MessageMenuSnapshot, MenuID: pasta.NodeMenuID(n.id), MenuGeneration: 1},
19✔
188
                Blocks:      []formular.Block{n.menuBlock()},
19✔
189
        })
19✔
190
}
19✔
191

192
func (n *boolNode) sendMenuBlock() {
54✔
193
        if n.w == nil || n.id == 0 {
54✔
194
                return
×
195
        }
×
196
        n.w.SendNodeMenuMsg(n.id, formular.BlockSnapshotMessage{
54✔
197
                MessageBase: formular.MessageBase{Type: formular.MessageBlockSnapshot, MenuID: pasta.NodeMenuID(n.id), MenuGeneration: 1, BlockGeneration: 1},
54✔
198
                Block:       n.menuBlock(),
54✔
199
        })
54✔
200
}
201

202
func (n *boolNode) menuBlock() formular.Block {
73✔
203
        return formular.Block{
73✔
204
                ID: "state", Order: 10, Generation: 1,
73✔
205
                Items: []formular.Item{{
73✔
206
                        Type:  formular.ItemField,
73✔
207
                        ID:    "value",
73✔
208
                        Label: "Value",
73✔
209
                        Field: &formular.Field{Kind: formular.FieldCheckbox, Value: n.value, Readonly: true},
73✔
210
                }},
73✔
211
        }
73✔
212
}
73✔
213

214
func boolLabel(value bool) string {
117✔
215
        if value {
174✔
216
                return "true"
57✔
217
        }
57✔
218
        return "false"
60✔
219
}
220

221
func isBoolRequest(payload any) bool {
22✔
222
        _, ok := payload.(RequestValue)
22✔
223
        return ok
22✔
224
}
22✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc