github.com/nevalang/neva@v0.23.1-0.20240507185603-7696a9bb8dda/internal/compiler/parser/parser_test.go (about) 1 package parser 2 3 import ( 4 "testing" 5 6 "github.com/nevalang/neva/internal/compiler" 7 src "github.com/nevalang/neva/internal/compiler/sourcecode" 8 "github.com/stretchr/testify/require" 9 ) 10 11 // userSender.pet.name -> println -> :stop 12 func TestParser_ParseFile_StructSelectorsWithLonelyChain(t *testing.T) { 13 text := []byte(` 14 component C1() () { 15 userSender.pet.name -> println -> :stop 16 }`, 17 ) 18 p := New(false) 19 got, err := p.parseFile(src.Location{}, text) 20 require.True(t, err == nil) 21 22 net := got.Entities["C1"].Component.Net 23 require.Equal(t, 2, len(net)) 24 25 conn := net[0].Normal 26 require.Equal(t, "userSender", conn.SenderSide.PortAddr.Node) 27 require.Equal(t, "", conn.SenderSide.PortAddr.Port) 28 require.Equal(t, "pet", conn.SenderSide.Selectors[0]) 29 require.Equal(t, "name", conn.SenderSide.Selectors[1]) 30 require.Equal(t, "println", conn.ReceiverSide.Receivers[0].PortAddr.Node) 31 require.Equal(t, "", conn.ReceiverSide.Receivers[0].PortAddr.Port) 32 33 conn = net[1].Normal 34 require.Equal(t, "println", conn.SenderSide.PortAddr.Node) 35 require.Equal(t, "", conn.SenderSide.PortAddr.Port) 36 require.Equal(t, "stop", conn.ReceiverSide.Receivers[0].PortAddr.Port) 37 } 38 39 func TestParser_ParseFile_PortlessArrPortAddr(t *testing.T) { 40 text := []byte(` 41 component C1() () { 42 foo[0] -> bar[255] 43 } 44 `) 45 46 p := New(false) 47 48 got, err := p.parseFile(src.Location{}, text) 49 require.Equal(t, true, err == nil) 50 51 net := got.Entities["C1"].Component.Net 52 conn := net[0].Normal 53 54 // foo[0]-> 55 require.Equal(t, "foo", conn.SenderSide.PortAddr.Node) 56 require.Equal(t, "", conn.SenderSide.PortAddr.Port) 57 require.Equal(t, compiler.Pointer(uint8(0)), conn.SenderSide.PortAddr.Idx) 58 59 // ->bar[255] 60 require.Equal(t, "bar", conn.ReceiverSide.Receivers[0].PortAddr.Node) 61 require.Equal(t, "", conn.ReceiverSide.Receivers[0].PortAddr.Port) 62 require.Equal(t, compiler.Pointer(uint8(255)), conn.ReceiverSide.Receivers[0].PortAddr.Idx) 63 } 64 65 func TestParser_ParseFile_ChainedConnectionsWithDefer(t *testing.T) { 66 text := []byte(` 67 component C1() () { 68 :start -> (foo -> bar -> :stop) 69 } 70 `) 71 72 p := New(false) 73 74 got, err := p.parseFile(src.Location{}, text) 75 require.True(t, err == nil) 76 77 net := got.Entities["C1"].Component.Net 78 require.Equal(t, 2, len(net)) 79 } 80 81 func TestParser_ParseFile_LonelyPorts(t *testing.T) { 82 text := []byte(` 83 component C1() () { 84 :port -> lonely 85 lonely -> :port 86 :port -> lonely -> :port 87 } 88 `) 89 90 p := New(false) 91 92 got, err := p.parseFile(src.Location{}, text) 93 require.True(t, err == nil) 94 95 // 1) :port -> lonely 96 // 2) lonely -> :port 97 // 3) :port -> lonely 98 // 4) lonely -> :port 99 net := got.Entities["C1"].Component.Net 100 require.Equal(t, 4, len(net)) 101 102 // 1) :port -> lonely 103 receiverPortAddr := net[0].Normal.ReceiverSide.Receivers[0].PortAddr 104 require.Equal(t, "lonely", receiverPortAddr.Node) 105 require.Equal(t, "", receiverPortAddr.Port) 106 107 // 2) lonely -> :port 108 senderPortAddr := net[1].Normal.SenderSide.PortAddr 109 require.Equal(t, "lonely", senderPortAddr.Node) 110 require.Equal(t, "", senderPortAddr.Port) 111 112 // 3) :port -> lonely 113 receiverPortAddr = net[2].Normal.ReceiverSide.Receivers[0].PortAddr 114 require.Equal(t, "lonely", receiverPortAddr.Node) 115 require.Equal(t, "", receiverPortAddr.Port) 116 117 // 4) lonely -> :port 118 senderPortAddr = net[3].Normal.SenderSide.PortAddr 119 require.Equal(t, "lonely", senderPortAddr.Node) 120 require.Equal(t, "", senderPortAddr.Port) 121 } 122 123 func TestParser_ParseFile_ChainedConnections(t *testing.T) { 124 text := []byte(` 125 component C1() () { :in -> n1:p1 -> :out } 126 `) 127 128 p := New(false) 129 130 got, err := p.parseFile(src.Location{}, text) 131 require.True(t, err == nil) 132 133 net := got.Entities["C1"].Component.Net 134 require.Equal(t, 2, len(net)) 135 } 136 137 func TestParser_ParseFile_Comments(t *testing.T) { 138 text := []byte(` 139 // comment 140 `) 141 142 p := New(false) 143 144 _, err := p.parseFile(src.Location{}, text) 145 require.True(t, err == nil) 146 } 147 148 func TestParser_ParseFile_Directives(t *testing.T) { 149 text := []byte(` 150 component { 151 #extern(d1) 152 C1() () 153 154 #extern(d2) 155 C2() () { 156 nodes { 157 #bind(d3) 158 n1 C1 159 160 #bind(d4) 161 n2 C1 162 } 163 } 164 165 #autoports 166 C3() () 167 168 #extern(d5) 169 #autoports 170 C4() () 171 } 172 `) 173 174 p := New(false) 175 176 got, err := p.parseFile(src.Location{}, text) 177 require.True(t, err == nil) 178 179 d1 := got.Entities["C1"].Component.Directives[compiler.ExternDirective][0] 180 require.Equal(t, "d1", d1) 181 182 c2 := got.Entities["C2"].Component 183 184 d2 := c2.Directives[compiler.ExternDirective][0] 185 require.Equal(t, "d2", d2) 186 187 d3 := c2.Nodes["n1"].Directives[compiler.BindDirective][0] 188 require.Equal(t, "d3", d3) 189 190 d4 := c2.Nodes["n2"].Directives[compiler.BindDirective][0] 191 require.Equal(t, "d4", d4) 192 193 c3 := got.Entities["C3"].Component 194 _, ok := c3.Directives[compiler.AutoportsDirective] 195 require.Equal(t, true, ok) 196 197 c4 := got.Entities["C4"].Component 198 d5, ok := c4.Directives[compiler.ExternDirective] 199 require.Equal(t, true, ok) 200 require.Equal(t, "d5", d5[0]) 201 _, ok = c4.Directives[compiler.AutoportsDirective] 202 require.Equal(t, true, ok) 203 } 204 205 func TestParser_ParseFile_IONodes(t *testing.T) { 206 text := []byte(` 207 component C1(start any) (stop any) { 208 :start -> :stop 209 } 210 `) 211 212 p := New(false) 213 214 got, err := p.parseFile(src.Location{}, text) 215 require.True(t, err == nil) 216 217 conn := got.Entities["C1"].Component.Net[0] 218 219 sender := conn.Normal.SenderSide.PortAddr.Node 220 require.Equal(t, "in", sender) 221 222 receiver := conn.Normal.ReceiverSide.Receivers[0].PortAddr.Node 223 require.Equal(t, "out", receiver) 224 } 225 226 func TestParser_ParseFile_AnonymousNodes(t *testing.T) { 227 text := []byte(` 228 component C1(start any) (stop any) { 229 nodes { 230 Scanner 231 Printer<int> 232 } 233 } 234 `) 235 236 p := New(false) 237 238 got, err := p.parseFile(src.Location{}, text) 239 require.True(t, err == nil) 240 241 nodes := got.Entities["C1"].Component.Nodes 242 243 _, ok := nodes["scanner"] 244 require.Equal(t, true, ok) 245 246 _, ok = nodes["printer"] 247 require.Equal(t, true, ok) 248 } 249 250 func TestParser_ParseFile_EnumLiterals(t *testing.T) { 251 text := []byte(` 252 const c0 Enum = Enum1::Foo 253 const c1 pkg.Enum = pkg.Enum2::Bar 254 `) 255 256 p := New(false) 257 258 got, err := p.parseFile(src.Location{}, text) 259 require.True(t, err == nil) 260 261 enum := got.Entities["c0"].Const.Message.Enum 262 require.Equal(t, "", enum.EnumRef.Pkg) 263 require.Equal(t, "Enum1", enum.EnumRef.Name) 264 require.Equal(t, "Foo", enum.MemberName) 265 266 enum = got.Entities["c1"].Const.Message.Enum 267 require.Equal(t, "pkg", enum.EnumRef.Pkg) 268 require.Equal(t, "Enum2", enum.EnumRef.Name) 269 require.Equal(t, "Bar", enum.MemberName) 270 } 271 272 func TestParser_ParseFile_EnumLiteralSenders(t *testing.T) { 273 text := []byte(` 274 component C1() () { 275 Foo::Bar -> :out 276 foo.Bar::Baz -> :out 277 } 278 `) 279 280 p := New(false) 281 282 got, err := p.parseFile(src.Location{}, text) 283 require.True(t, err == nil) 284 285 conn := got.Entities["C1"].Component.Net[0] 286 287 senderEnum := conn.Normal.SenderSide.Const.Message.Enum 288 require.Equal(t, "", senderEnum.EnumRef.Pkg) 289 require.Equal(t, "Foo", senderEnum.EnumRef.Name) 290 require.Equal(t, "Bar", senderEnum.MemberName) 291 292 conn = got.Entities["C1"].Component.Net[1] 293 senderEnum = conn.Normal.SenderSide.Const.Message.Enum 294 require.Equal(t, "foo", senderEnum.EnumRef.Pkg) 295 require.Equal(t, "Bar", senderEnum.EnumRef.Name) 296 require.Equal(t, "Baz", senderEnum.MemberName) 297 }