github.com/goki/ki@v1.1.11/ki/node_test.go (about) 1 // Copyright (c) 2018, The GoKi Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package ki 6 7 import ( 8 "bytes" 9 "fmt" 10 "io/ioutil" 11 "reflect" 12 "strings" 13 "testing" 14 15 "github.com/goki/ki/kit" 16 ) 17 18 type NodeEmbed struct { 19 Node 20 Mbr1 string 21 Mbr2 int 22 } 23 24 var NodeEmbedProps = Props{ 25 "intprop": -17, 26 "floatprop": 3.1415, 27 "stringprop": "type string", 28 } 29 30 var KiT_NodeEmbed = kit.Types.AddType(&NodeEmbed{}, NodeEmbedProps) 31 32 type NodeField struct { 33 NodeEmbed 34 Field1 NodeEmbed 35 } 36 37 var KiT_NodeField = kit.Types.AddType(&NodeField{}, nil) 38 39 type NodeField2 struct { 40 NodeField 41 Field2 NodeEmbed 42 PtrIgnore *NodeEmbed 43 } 44 45 var KiT_NodeField2 = kit.Types.AddType(&NodeField2{}, nil) 46 47 func TestNodeAddChild(t *testing.T) { 48 parent := NodeEmbed{} 49 parent.InitName(&parent, "par1") 50 child := NodeEmbed{} 51 // Note: must pass child.KiNode as a pointer -- if it is a plain Node it is ok but 52 // as a member of a struct, for somewhat obscure reasons having to do with the 53 // fact that an interface is implicitly a pointer, you need to pass as a pointer here 54 parent.AddChild(&child) 55 child.SetName("child1") 56 if len(parent.Kids) != 1 { 57 t.Errorf("Children length != 1, was %d", len(parent.Kids)) 58 } 59 if child.Parent() == nil { 60 t.Errorf("child parent is nil") 61 } 62 if child.Path() != "/par1/child1" { 63 t.Errorf("child path != correct, was %v", child.Path()) 64 } 65 } 66 67 func TestNodeEmbedAddChild(t *testing.T) { 68 parent := NodeEmbed{} 69 parent.InitName(&parent, "par1") 70 child := NodeEmbed{} 71 // Note: must pass child as a pointer -- if it is a plain Node it is ok but 72 // as a member of a struct, for somewhat obscure reasons having to do with the 73 // fact that an interface is implicitly a pointer, you need to pass as a pointer here 74 parent.AddChild(&child) 75 child.SetName("child1") 76 if len(parent.Kids) != 1 { 77 t.Errorf("Children length != 1, was %d", len(parent.Kids)) 78 } 79 if child.Path() != "/par1/child1" { 80 t.Errorf("child path != correct, was %v", child.Path()) 81 } 82 } 83 84 func TestNodeEmbedAddNewChild(t *testing.T) { 85 // nod := Node{} 86 parent := NodeEmbed{} 87 parent.InitName(&parent, "par1") 88 typ := reflect.TypeOf(parent) 89 child := parent.AddNewChild(typ, "child1") 90 if len(parent.Kids) != 1 { 91 t.Errorf("Children length != 1, was %d", len(parent.Kids)) 92 } 93 if child.Path() != "/par1/child1" { 94 t.Errorf("child path != correct, was %v", child.Path()) 95 } 96 if reflect.TypeOf(child).Elem() != Type(parent.This()) { 97 t.Errorf("child type != correct, was %T", child) 98 } 99 } 100 101 func TestNodeUniqueNames(t *testing.T) { 102 parent := NodeEmbed{} 103 parent.InitName(&parent, "par1") 104 typ := reflect.TypeOf(parent) 105 child := parent.AddNewChild(typ, "child1") 106 child2 := parent.AddNewChild(typ, "child1") 107 child3 := parent.AddNewChild(typ, "child1") 108 if len(parent.Kids) != 3 { 109 t.Errorf("Children length != 3, was %d", len(parent.Kids)) 110 } 111 UniquifyNamesAll(parent.This()) 112 if pth := child.Path(); pth != "/par1/child1" { 113 t.Errorf("child path != correct, was %v", pth) 114 } 115 if pth := child2.Path(); pth != "/par1/child1_001" { 116 t.Errorf("child2 path != correct, was %v", pth) 117 } 118 if pth := child3.Path(); pth != "/par1/child1_002" { 119 t.Errorf("child3 path != correct, was %v", pth) 120 } 121 122 } 123 124 func TestNodeEscapePaths(t *testing.T) { 125 parent := NodeEmbed{} 126 parent.InitName(&parent, "par1") 127 typ := reflect.TypeOf(parent) 128 child := parent.AddNewChild(typ, "child1.go") 129 child2 := parent.AddNewChild(typ, "child1/child1") 130 child3 := parent.AddNewChild(typ, "child1/child1.go") 131 schild2 := child2.AddNewChild(typ, "subchild1") 132 if len(parent.Kids) != 3 { 133 t.Errorf("Children length != 3, was %d", len(parent.Kids)) 134 } 135 if pth := child.Path(); pth != `/par1/child1\,go` { 136 t.Errorf("child path != correct, was %v", pth) 137 } 138 if pth := child2.Path(); pth != `/par1/child1\\child1` { 139 t.Errorf("child2 path != correct, was %v", pth) 140 } 141 if pth := child3.Path(); pth != `/par1/child1\\child1\,go` { 142 t.Errorf("child3 path != correct, was %v", pth) 143 } 144 ch := parent.FindPath(child.Path()) 145 if ch != child { 146 t.Errorf("child path not found in parent") 147 } 148 ch = parent.FindPath(child3.Path()) 149 if ch != child3 { 150 t.Errorf("child3 path not found in parent") 151 } 152 ch = parent.FindPath(child3.Path()) 153 if ch != child3 { 154 t.Errorf("child3 path not found in parent") 155 } 156 ch = parent.FindPath(schild2.Path()) 157 if ch != schild2 { 158 t.Errorf("schild2 path not found in parent") 159 } 160 ch = child2.FindPath(schild2.Path()) 161 if ch != schild2 { 162 t.Errorf("schild2 path not found in child2") 163 } 164 } 165 166 func TestNodeDeleteChild(t *testing.T) { 167 parent := NodeEmbed{} 168 parent.InitName(&parent, "par1") 169 typ := reflect.TypeOf(parent) 170 child := parent.AddNewChild(typ, "child1") 171 parent.DeleteChild(child, true) 172 if len(parent.Kids) != 0 { 173 t.Errorf("Children length != 0, was %d", len(parent.Kids)) 174 } 175 if len(DelMgr.Dels) != 0 { // note: even though using destroy, UpdateEnd does destroy 176 t.Errorf("Deleted length != 0, was %d", len(DelMgr.Dels)) 177 } 178 } 179 180 func TestNodeDeleteChildName(t *testing.T) { 181 parent := NodeEmbed{} 182 parent.InitName(&parent, "par1") 183 typ := reflect.TypeOf(parent) 184 parent.AddNewChild(typ, "child1") 185 parent.DeleteChildByName("child1", true) 186 if len(parent.Kids) != 0 { 187 t.Errorf("Children length != 0, was %d", len(parent.Kids)) 188 } 189 if len(DelMgr.Dels) != 0 { // note: even though using destroy, UpdateEnd does destroy 190 t.Errorf("Deleted length != 0, was %d", len(DelMgr.Dels)) 191 } 192 } 193 194 func TestNodeFindName(t *testing.T) { 195 names := [...]string{"name0", "name1", "name2", "name3", "name4", "name5"} 196 parent := Node{} 197 parent.InitName(&parent, "par") 198 typ := reflect.TypeOf(parent) 199 for _, nm := range names { 200 parent.AddNewChild(typ, nm) 201 } 202 if len(parent.Kids) != len(names) { 203 t.Errorf("Children length != n, was %d", len(parent.Kids)) 204 } 205 for i, nm := range names { 206 for st := range names { // test all starting indexes 207 idx, ok := parent.Children().IndexByName(nm, st) 208 if !ok || idx != i { 209 t.Errorf("find index was not correct val of %d, was %d", i, idx) 210 } 211 } 212 } 213 } 214 215 func TestNodeFindNameUnique(t *testing.T) { 216 names := [...]string{"child", "child_001", "child_002", "child_003", "child_004", "child_005"} 217 parent := Node{} 218 parent.InitName(&parent, "par") 219 typ := reflect.TypeOf(parent) 220 for range names { 221 parent.AddNewChild(typ, "child") 222 } 223 if len(parent.Kids) != len(names) { 224 t.Errorf("Children length != n, was %d", len(parent.Kids)) 225 } 226 if UniqueNameCheckAll(parent.This()) { 227 t.Errorf("UniqeNameCheckAll failed: Children are not unique!") 228 } 229 UniquifyNamesAll(parent.This()) 230 for i, nm := range names { 231 for st := range names { // test all starting indexes 232 idx, ok := parent.Children().IndexByName(nm, st) 233 if !ok || idx != i { 234 t.Errorf("find index was not correct val of %d, was %d", i, idx) 235 } 236 } 237 } 238 } 239 240 func TestNodeFindType(t *testing.T) { 241 parent := Node{} 242 parent.InitName(&parent, "par") 243 parent.AddNewChild(KiT_NodeEmbed, "child1") 244 parent.AddNewChild(KiT_Node, "child2") 245 idx, ok := parent.Children().IndexByType(KiT_NodeEmbed, NoEmbeds, 0) 246 if !ok || idx != 0 { 247 t.Errorf("find index was not correct val of %d, was %d", 0, idx) 248 } 249 idx, ok = parent.Children().IndexByType(KiT_Node, NoEmbeds, 0) 250 if !ok || idx != 1 { 251 t.Errorf("find index was not correct val of %d, was %d", 1, idx) 252 } 253 _, err := parent.Children().ElemByTypeTry(KiT_Node, NoEmbeds, 0) 254 if err != nil { 255 t.Error(err) 256 } 257 } 258 259 func TestNodeMove(t *testing.T) { 260 parent := NodeEmbed{} 261 parent.InitName(&parent, "par1") 262 typ := reflect.TypeOf(parent) 263 parent.Mbr1 = "bloop" 264 parent.Mbr2 = 32 265 // child1 := 266 parent.AddNewChild(typ, "child0") 267 var child2 = parent.AddNewChild(typ, "child1").(*NodeEmbed) 268 // child3 := 269 parent.AddNewChild(typ, "child2") 270 //schild2 := 271 child2.AddNewChild(typ, "subchild1") 272 // child4 := 273 parent.AddNewChild(typ, "child3") 274 275 bf := fmt.Sprintf("mv before:\n%v\n", parent.Kids) 276 parent.Children().Move(3, 1) 277 a31 := fmt.Sprintf("mv 3 -> 1:\n%v\n", parent.Kids) 278 parent.Children().Move(0, 3) 279 a03 := fmt.Sprintf("mv 0 -> 3:\n%v\n", parent.Kids) 280 parent.Children().Move(1, 2) 281 a12 := fmt.Sprintf("mv 1 -> 2:\n%v\n", parent.Kids) 282 283 bft := `mv before: 284 [/par1/child0 /par1/child1 /par1/child2 /par1/child3] 285 ` 286 if bf != bft { 287 t.Errorf("move error\n%v !=\n%v", bf, bft) 288 } 289 a31t := `mv 3 -> 1: 290 [/par1/child0 /par1/child3 /par1/child1 /par1/child2] 291 ` 292 if a31 != a31t { 293 t.Errorf("move error\n%v !=\n%v", a31, a31t) 294 } 295 a03t := `mv 0 -> 3: 296 [/par1/child3 /par1/child1 /par1/child2 /par1/child0] 297 ` 298 if a03 != a03t { 299 t.Errorf("move error\n%v !=\n%v", a03, a03t) 300 } 301 a12t := `mv 1 -> 2: 302 [/par1/child3 /par1/child2 /par1/child1 /par1/child0] 303 ` 304 if a12 != a12t { 305 t.Errorf("move error\n%v !=\n%v", a12, a12t) 306 } 307 } 308 309 func TestNodeConfig(t *testing.T) { 310 parent := NodeEmbed{} 311 parent.InitName(&parent, "par1") 312 typ := reflect.TypeOf(parent) 313 parent.Mbr1 = "bloop" 314 parent.Mbr2 = 32 315 // child1 := 316 parent.AddNewChild(typ, "child0") 317 var child2 = parent.AddNewChild(typ, "child1").(*NodeEmbed) 318 // child3 := 319 parent.AddNewChild(typ, "child2") 320 //schild2 := 321 child2.AddNewChild(typ, "subchild1") 322 // child4 := 323 parent.AddNewChild(typ, "child3") 324 325 config1 := kit.TypeAndNameList{ 326 {Type: KiT_NodeEmbed, Name: "child2"}, 327 {Type: KiT_NodeEmbed, Name: "child3"}, 328 {Type: KiT_NodeEmbed, Name: "child1"}, 329 } 330 331 // bf := fmt.Sprintf("mv before:\n%v\n", parent.Kids) 332 333 mods, updt := parent.ConfigChildren(config1) 334 if mods { 335 parent.UpdateEnd(updt) 336 } 337 338 cf1 := fmt.Sprintf("config1:\n%v\n", parent.Kids) 339 340 // config2 := kit.TypeAndNameList{ 341 // {KiT_NodeEmbed, "child4"}, 342 // {KiT_Node, "child1"}, // note: changing this to Node type removes child1.subchild1 343 // {KiT_NodeEmbed, "child5"}, 344 // {KiT_NodeEmbed, "child3"}, 345 // {KiT_NodeEmbed, "child6"}, 346 // } 347 348 config3 := kit.TypeAndNameList{} 349 // fmt.Printf("NodeEmbed type name: %v\n", kit.FullTypeName(KiT_NodeEmbed)) 350 netn := kit.Types.TypeName(KiT_NodeEmbed) 351 ntn := kit.Types.TypeName(KiT_Node) 352 err := config3.SetFromString("{" + netn + ", child4}, {" + ntn + ", child1}, {" + netn + ", child5}, {" + netn + ", child3}, {" + netn + ", child6}") 353 if err != nil { 354 t.Errorf("%v", err) 355 } 356 357 mods, updt = parent.ConfigChildren(config3) 358 if mods { 359 parent.UpdateEnd(updt) 360 } 361 362 cf2 := fmt.Sprintf("config2:\n%v\n", parent.Kids) 363 364 cf1t := `config1: 365 [/par1/child2 /par1/child3 /par1/child1] 366 ` 367 if cf1 != cf1t { 368 t.Errorf("config error\n%v !=\n%v", cf1, cf1t) 369 } 370 371 cf2t := `config2: 372 [/par1/child4 /par1/child1 /par1/child5 /par1/child3 /par1/child6] 373 ` 374 if cf2 != cf2t { 375 t.Errorf("config error\n%v !=\n%v", cf2, cf2t) 376 } 377 } 378 379 ////////////////////////////////////////// 380 // JSON I/O 381 382 func TestNodeJSONSave(t *testing.T) { 383 parent := NodeEmbed{} 384 parent.InitName(&parent, "par1") 385 typ := reflect.TypeOf(parent) 386 parent.Mbr1 = "bloop" 387 parent.Mbr2 = 32 388 // child1 := 389 parent.AddNewChild(typ, "child1") 390 var child2 = parent.AddNewChild(typ, "child1").(*NodeEmbed) 391 // child3 := 392 parent.AddNewChild(typ, "child1") 393 child2.AddNewChild(typ, "subchild1") 394 395 var buf bytes.Buffer 396 err := parent.WriteJSON(&buf, true) 397 if err != nil { 398 t.Error(err) 399 // } else { 400 // fmt.Printf("json output:\n%v\n", string(buf.Bytes())) 401 } 402 b := buf.Bytes() 403 404 tstload := NodeEmbed{} 405 tstload.InitName(&tstload, "") 406 err = tstload.ReadJSON(bytes.NewReader(b)) 407 if err != nil { 408 t.Error(err) 409 } else { 410 var buf2 bytes.Buffer 411 err = tstload.WriteJSON(&buf2, true) 412 if err != nil { 413 t.Error(err) 414 } 415 tstb := buf2.Bytes() 416 // fmt.Printf("test loaded json output: %v\n", string(tstb)) 417 if !bytes.Equal(tstb, b) { 418 t.Error("original and unmarshal'd json rep are not equivalent") 419 } 420 } 421 422 nwnd, err := ReadNewJSON(bytes.NewReader(b)) 423 if err != nil { 424 t.Error(err) 425 } else { 426 var buf2 bytes.Buffer 427 err = nwnd.WriteJSON(&buf2, true) 428 if err != nil { 429 t.Error(err) 430 } 431 tstb := buf2.Bytes() 432 // fmt.Printf("test loaded json output: %v\n", string(tstb)) 433 if !bytes.Equal(tstb, b) { 434 t.Error("original and unmarshal'd json rep are not equivalent") 435 } 436 } 437 } 438 439 func TestNodeXMLSave(t *testing.T) { 440 parent := NodeEmbed{} 441 parent.InitName(&parent, "par1") 442 typ := reflect.TypeOf(parent) 443 parent.Mbr1 = "bloop" 444 parent.Mbr2 = 32 445 // child1 := 446 parent.AddNewChild(typ, "child1") 447 var child2 = parent.AddNewChild(typ, "child1").(*NodeEmbed) 448 // child3 := 449 parent.AddNewChild(typ, "child1") 450 child2.AddNewChild(typ, "subchild1") 451 452 var buf bytes.Buffer 453 err := parent.WriteXML(&buf, true) 454 if err != nil { 455 t.Error(err) 456 // } else { 457 // fmt.Printf("xml output:\n%v\n", string(buf.Bytes())) 458 } 459 b := buf.Bytes() 460 461 tstload := NodeEmbed{} 462 tstload.InitName(&tstload, "") 463 err = tstload.ReadXML(bytes.NewReader(b)) 464 if err != nil { 465 t.Error(err) 466 } else { 467 var buf2 bytes.Buffer 468 if err != nil { 469 t.Error(err) 470 } 471 err := tstload.WriteXML(&buf2, true) 472 if err != nil { 473 t.Error(err) 474 } 475 tstb := buf2.Bytes() 476 // fmt.Printf("test loaded json output:\n%v\n", string(tstb)) 477 if !bytes.Equal(tstb, b) { 478 t.Error("original and unmarshal'd XML rep are not equivalent") 479 } 480 } 481 } 482 483 ////////////////////////////////////////// 484 // function calling 485 486 func TestNodeCallFun(t *testing.T) { 487 parent := NodeEmbed{} 488 parent.InitName(&parent, "par1") 489 typ := reflect.TypeOf(parent) 490 parent.Mbr1 = "bloop" 491 parent.Mbr2 = 32 492 // child1 := 493 parent.AddNewChild(typ, "child1") 494 child2 := parent.AddNewChild(typ, "child1") 495 // child3 := 496 parent.AddNewChild(typ, "child1") 497 schild2 := child2.AddNewChild(typ, "subchild1") 498 UniquifyNames(parent.This()) 499 500 res := make([]string, 0, 10) 501 parent.FuncDownMeFirst(0, "fun_down", func(k Ki, level int, d interface{}) bool { 502 res = append(res, fmt.Sprintf("[%v, %v, lev %v]", k.Name(), d, level)) 503 return true 504 }) 505 506 trg := []string{"[par1, fun_down, lev 0]", "[child1, fun_down, lev 1]", "[child1_001, fun_down, lev 1]", "[subchild1, fun_down, lev 2]", "[child1_002, fun_down, lev 1]"} 507 if !reflect.DeepEqual(res, trg) { 508 t.Errorf("FuncDown error -- results:\n%v\n != target:\n%v\n", res, trg) 509 } 510 res = res[:0] 511 512 // test return = false case 513 parent.FuncDownMeFirst(0, "fun_down", func(k Ki, level int, d interface{}) bool { 514 res = append(res, fmt.Sprintf("[%v, %v, lev %v]", k.Name(), d, level)) 515 if k.Name() == "child1_001" { 516 return Break 517 } 518 return Continue 519 }) 520 521 trg = []string{"[par1, fun_down, lev 0]", "[child1, fun_down, lev 1]", "[child1_001, fun_down, lev 1]", "[child1_002, fun_down, lev 1]"} 522 if !reflect.DeepEqual(res, trg) { 523 t.Errorf("FuncDown return false error -- results:\n%v\n != target:\n%v\n", res, trg) 524 } 525 res = res[:0] 526 527 schild2.FuncUp(0, "fun_up", func(k Ki, level int, d interface{}) bool { 528 res = append(res, fmt.Sprintf("%v, %v", k.Name(), d)) 529 return Continue 530 }) 531 // fmt.Printf("result: %v\n", res) 532 533 trg = []string{"subchild1, fun_up", "child1_001, fun_up", "par1, fun_up"} 534 if !reflect.DeepEqual(res, trg) { 535 t.Errorf("FuncUp error -- results: %v != target: %v\n", res, trg) 536 } 537 res = res[:0] 538 539 parent.FuncDownMeLast(0, "fun_down_me_last", func(k Ki, level int, d interface{}) bool { 540 return Continue 541 }, 542 func(k Ki, level int, d interface{}) bool { 543 res = append(res, fmt.Sprintf("[%v, %v, lev %v]", k.Name(), d, level)) 544 return Continue 545 }) 546 // fmt.Printf("node field fun result: %v\n", res) 547 trg = []string{"[child1, fun_down_me_last, lev 1]", "[subchild1, fun_down_me_last, lev 2]", "[child1_001, fun_down_me_last, lev 1]", "[child1_002, fun_down_me_last, lev 1]", "[par1, fun_down_me_last, lev 0]"} 548 if !reflect.DeepEqual(res, trg) { 549 t.Errorf("NodeField FuncDownMeLast error -- results:\n%v\n!= target:\n%v\n", res, trg) 550 } 551 res = res[:0] 552 553 // test for return = false working 554 parent.FuncDownMeLast(0, "fun_down_me_last", func(k Ki, level int, d interface{}) bool { 555 if k.Name() == "child1_001" { 556 return Break 557 } 558 return Continue 559 }, 560 func(k Ki, level int, d interface{}) bool { 561 if k.Name() == "child1_001" { 562 return Break 563 } 564 res = append(res, fmt.Sprintf("[%v, %v, lev %v]", k.Name(), d, level)) 565 return Continue 566 }) 567 // fmt.Printf("node field fun result: %v\n", res) 568 trg = []string{"[child1, fun_down_me_last, lev 1]", "[child1_002, fun_down_me_last, lev 1]", "[par1, fun_down_me_last, lev 0]"} 569 if !reflect.DeepEqual(res, trg) { 570 t.Errorf("NodeField FuncDownMeLast error -- results:\n%v\n!= target:\n%v\n", res, trg) 571 } 572 res = res[:0] 573 574 parent.FuncDownBreadthFirst(0, "fun_breadth", func(k Ki, level int, d interface{}) bool { 575 res = append(res, fmt.Sprintf("[%v, %v, lev %v]", k.Name(), d, level)) 576 return Continue 577 }) 578 // fmt.Printf("node field fun result: %v\n", res) 579 trg = []string{"[par1, fun_breadth, lev 0]", "[child1, fun_breadth, lev 1]", "[child1_001, fun_breadth, lev 1]", "[child1_002, fun_breadth, lev 1]", "[subchild1, fun_breadth, lev 2]"} 580 if !reflect.DeepEqual(res, trg) { 581 t.Errorf("NodeField FuncDownBreadthFirst error -- results:\n%v\n!= target:\n%v\n", res, trg) 582 } 583 res = res[:0] 584 585 // test for return false 586 parent.FuncDownBreadthFirst(0, "fun_breadth", func(k Ki, level int, d interface{}) bool { 587 if k.Name() == "child1_001" { 588 return Break 589 } 590 res = append(res, fmt.Sprintf("[%v, %v, lev %v]", k.Name(), d, level)) 591 return Continue 592 }) 593 // fmt.Printf("node field fun result: %v\n", res) 594 trg = []string{"[par1, fun_breadth, lev 0]", "[child1, fun_breadth, lev 1]", "[child1_002, fun_breadth, lev 1]"} 595 if !reflect.DeepEqual(res, trg) { 596 t.Errorf("NodeField FuncDownBreadthFirst error -- results:\n%v\n!= target:\n%v\n", res, trg) 597 } 598 res = res[:0] 599 } 600 601 func TestNodeUpdate(t *testing.T) { 602 parent := NodeEmbed{} 603 parent.InitName(&parent, "par1") 604 typ := reflect.TypeOf(parent) 605 parent.Mbr1 = "bloop" 606 parent.Mbr2 = 32 607 608 res := make([]string, 0, 10) 609 parent.NodeSignal().Connect(&parent, func(r, s Ki, sig int64, d interface{}) { 610 res = append(res, fmt.Sprintf("%v sig %v flags %v", s.Name(), NodeSignals(sig), 611 kit.BitFlagsToString((s.Flags()), FlagsN))) 612 }) 613 // child1 := 614 updt := parent.UpdateStart() 615 parent.SetChildAdded() 616 parent.AddNewChild(typ, "child1") 617 child2 := parent.AddNewChild(typ, "child1") 618 // child3 := 619 parent.UpdateEnd(updt) 620 updt = parent.UpdateStart() 621 parent.SetChildAdded() 622 parent.AddNewChild(typ, "child1") 623 parent.UpdateEnd(updt) 624 schild2 := child2.AddNewChild(typ, "subchild1") 625 child2.SetChildAdded() 626 parent.UpdateEnd(updt) 627 628 for ri := range res { 629 res[ri] = strings.Replace(res[ri], "HasNoKiFields|", "", -1) 630 } 631 // fmt.Printf("res: %v\n", res) 632 trg := []string{"par1 sig NodeSignalUpdated flags ChildAdded", "par1 sig NodeSignalUpdated flags ChildAdded", "par1 sig NodeSignalUpdated flags ChildAdded"} 633 if !reflect.DeepEqual(res, trg) { 634 t.Errorf("Add child sigs error -- results:\n%v\n!= target:\n%v\n", res, trg) 635 } 636 res = res[:0] 637 638 child2.NodeSignal().Connect(&parent, func(r, s Ki, sig int64, d interface{}) { 639 res = append(res, fmt.Sprintf("%v sig %v", s.Name(), NodeSignals(sig))) 640 }) 641 schild2.NodeSignal().Connect(&parent, func(r, s Ki, sig int64, d interface{}) { 642 res = append(res, fmt.Sprintf("%v sig %v", s.Name(), NodeSignals(sig))) 643 }) 644 645 // fmt.Print("\nnode update top starting\n") 646 updt = child2.UpdateStart() 647 updt2 := schild2.UpdateStart() 648 schild2.UpdateEnd(updt2) 649 child2.UpdateEnd(updt) 650 651 // fmt.Printf("res: %v\n", res) 652 trg = []string{"child1 sig NodeSignalUpdated"} 653 if !reflect.DeepEqual(res, trg) { 654 t.Errorf("update signal only top error -- results: %v != target: %v\n", res, trg) 655 } 656 res = res[:0] 657 658 UniquifyNamesAll(parent.This()) 659 660 parent.FuncDownMeFirst(0, "upcnt", func(n Ki, level int, d interface{}) bool { 661 res = append(res, fmt.Sprintf("%v %v", n.Name(), n.IsUpdating())) 662 return Continue 663 }) 664 // fmt.Printf("res: %v\n", res) 665 666 trg = []string{"par1 false", "child1 false", "child1_001 false", "subchild1 false", "child1_002 false"} 667 if !reflect.DeepEqual(res, trg) { 668 t.Errorf("update counts error -- results: %v != target: %v\n", res, trg) 669 } 670 671 } 672 673 func TestProps(t *testing.T) { 674 parent := NodeEmbed{} 675 parent.InitName(&parent, "par1") 676 typ := reflect.TypeOf(parent) 677 parent.Mbr1 = "bloop" 678 parent.Mbr2 = 32 679 680 res := make([]string, 0, 10) 681 parent.NodeSignal().Connect(&parent, func(r, s Ki, sig int64, d interface{}) { 682 res = append(res, fmt.Sprintf("%v sig %v", s.Name(), sig)) 683 }) 684 // child1 := 685 parent.AddNewChild(typ, "child1") 686 child2 := parent.AddNewChild(typ, "child1") 687 // child3 := 688 updt := parent.UpdateStart() 689 parent.AddNewChild(typ, "child1") 690 parent.UpdateEnd(updt) 691 schild2 := child2.AddNewChild(typ, "subchild1") 692 693 parent.SetProp("intprop", 42) 694 pprop, ok := kit.ToInt(parent.Prop("intprop")) 695 if !ok || pprop != 42 { 696 t.Errorf("TestProps error -- pprop %v != %v\n", pprop, 42) 697 } 698 sprop, ok := schild2.PropInherit("intprop", Inherit, NoTypeProps) 699 if !ok { 700 t.Errorf("TestProps error -- intprop inherited not found\n") 701 } 702 sint, ok := kit.ToInt(sprop) 703 if !ok || sprop != 42 { 704 t.Errorf("TestProps error -- intprop inherited %v != %v\n", sint, 42) 705 } 706 sprop, ok = schild2.PropInherit("intprop", NoInherit, NoTypeProps) 707 if ok { 708 t.Errorf("TestProps error -- intprop should not be found! was: %v\n", sprop) 709 } 710 711 parent.SetProp("floatprop", 42.0) 712 sprop, ok = schild2.PropInherit("floatprop", Inherit, NoTypeProps) 713 if !ok { 714 t.Errorf("TestProps error -- floatprop inherited not found\n") 715 } 716 spropf, ok := kit.ToFloat(sprop) 717 if !ok || spropf != 42.0 { 718 t.Errorf("TestProps error -- floatprop inherited %v != %v\n", spropf, 42.0) 719 } 720 721 tstr := "test string" 722 parent.SetProp("stringprop", tstr) 723 sprop, ok = schild2.PropInherit("stringprop", Inherit, NoTypeProps) 724 if !ok { 725 t.Errorf("TestProps error -- stringprop not found\n") 726 } 727 sprops := kit.ToString(sprop) 728 if sprops != tstr { 729 t.Errorf("TestProps error -- sprops inherited %v != %v\n", sprops, tstr) 730 } 731 732 parent.DeleteProp("floatprop") 733 sprop, ok = schild2.PropInherit("floatprop", Inherit, NoTypeProps) 734 if ok { 735 t.Errorf("TestProps error -- floatprop should be gone\n") 736 } 737 738 sprop, ok = parent.PropInherit("floatprop", Inherit, TypeProps) 739 if !ok { 740 t.Errorf("TestProps error -- floatprop on type not found\n") 741 } 742 spropf, ok = kit.ToFloat(sprop) 743 if !ok || spropf != 3.1415 { 744 t.Errorf("TestProps error -- floatprop from type %v != %v\n", spropf, 3.1415) 745 } 746 } 747 748 func TestTreeMod(t *testing.T) { 749 SignalTrace = true 750 sigs := "" 751 SignalTraceString = &sigs 752 753 tree1 := Node{} 754 typ := reflect.TypeOf(tree1) 755 tree1.InitName(&tree1, "tree1") 756 // child11 := 757 tree1.AddNewChild(typ, "child11") 758 child12 := tree1.AddNewChild(typ, "child12") 759 // child13 := 760 tree1.AddNewChild(typ, "child13") 761 // schild12 := 762 child12.AddNewChild(typ, "subchild12") 763 764 tree2 := Node{} 765 tree2.InitName(&tree2, "tree2") 766 // child21 := 767 tree2.AddNewChild(typ, "child21") 768 child22 := tree2.AddNewChild(typ, "child22") 769 // child23 := 770 tree2.AddNewChild(typ, "child23") 771 // schild22 := 772 child22.AddNewChild(typ, "subchild22") 773 774 // fmt.Printf("Setup Signals:\n%v", sigs) 775 sigs = "" 776 777 // fmt.Printf("#################################\n") 778 779 // fmt.Printf("Trees before:\n%v%v", tree1, tree2) 780 updt := tree2.UpdateStart() 781 tree2.SetChildAdded() 782 MoveToParent(child12.This(), tree2.This()) 783 tree2.UpdateEnd(updt) 784 785 // fmt.Printf("#################################\n") 786 // fmt.Printf("Trees after add child12 move:\n%v%v", tree1, tree2) 787 788 mvsigs := `ki.Signal Emit from: tree1 sig: NodeSignalUpdated data: 260 789 ki.Signal Emit from: tree2 sig: NodeSignalUpdated data: 132 790 ` 791 792 _ = mvsigs 793 // fmt.Printf("Move Signals:\n%v", sigs) 794 if sigs != mvsigs { 795 t.Errorf("TestTreeMod child12 move signals:\n%v\nnot as expected:\n%v\n", sigs, mvsigs) 796 } 797 sigs = "" 798 799 updt = tree2.UpdateStart() 800 tree2.DeleteChild(child12, true) 801 tree2.UpdateEnd(updt) 802 803 // fmt.Printf("#################################\n") 804 805 delsigs := `ki.Signal Emit from: child12 sig: NodeSignalDeleting data: <nil> 806 ki.Signal Emit from: subchild12 sig: NodeSignalDeleting data: <nil> 807 ki.Signal Emit from: tree2 sig: NodeSignalUpdated data: 260 808 ` 809 810 _ = delsigs 811 // fmt.Printf("Delete Signals:\n%v", sigs) 812 if sigs != delsigs { 813 t.Errorf("TestTreeMod child12 delete signals:\n%v\nnot as expected:\n%v\n", sigs, delsigs) 814 } 815 sigs = "" 816 817 } 818 819 func TestNodeFieldFunc(t *testing.T) { 820 parent := NodeField{} 821 parent.InitName(&parent, "par1") 822 res := make([]string, 0, 10) 823 parent.FuncDownMeFirst(0, "fun_down", func(k Ki, level int, d interface{}) bool { 824 res = append(res, fmt.Sprintf("[%v, %v, lev %v]", k.Name(), d, level)) 825 return Continue 826 }) 827 // fmt.Printf("node field fun result: %v\n", res) 828 829 trg := []string{"[par1, fun_down, lev 0]", "[Field1, fun_down, lev 1]"} 830 if !reflect.DeepEqual(res, trg) { 831 t.Errorf("NodeField FuncDown error -- results: %v != target: %v\n", res, trg) 832 } 833 res = res[:0] 834 835 par2 := NodeField2{} 836 par2.InitName(&par2, "par2") 837 par2.FuncDownMeFirst(0, "fun_down", func(k Ki, level int, d interface{}) bool { 838 res = append(res, fmt.Sprintf("[%v, %v, lev %v]", k.Name(), d, level)) 839 return Continue 840 }) 841 // fmt.Printf("node field fun result: %v\n", res) 842 trg = []string{"[par2, fun_down, lev 0]", "[Field1, fun_down, lev 1]", "[Field2, fun_down, lev 1]"} 843 if !reflect.DeepEqual(res, trg) { 844 t.Errorf("NodeField FuncDown error -- results: %v != target: %v\n", res, trg) 845 } 846 res = res[:0] 847 848 par2.FuncDownMeLast(0, "fun_down_me_last", func(k Ki, level int, d interface{}) bool { 849 return Continue 850 }, 851 func(k Ki, level int, d interface{}) bool { 852 res = append(res, fmt.Sprintf("[%v, %v, lev %v]", k.Name(), d, level)) 853 return Continue 854 }) 855 // fmt.Printf("node field fun result: %v\n", res) 856 trg = []string{"[Field1, fun_down_me_last, lev 1]", "[Field2, fun_down_me_last, lev 1]", "[par2, fun_down_me_last, lev 0]"} 857 if !reflect.DeepEqual(res, trg) { 858 t.Errorf("NodeField FuncDownMeLast error -- results:\n%v\n!= target:\n%v\n", res, trg) 859 } 860 res = res[:0] 861 } 862 863 func TestNodeFieldJSONSave(t *testing.T) { 864 parent := NodeField2{} 865 parent.InitName(&parent, "par1") 866 typ := reflect.TypeOf(parent) 867 parent.Mbr1 = "bloop" 868 parent.Mbr2 = 32 869 // child1 := 870 parent.AddNewChild(typ, "child1") 871 child2 := parent.AddNewChild(typ, "child1").(*NodeField2) 872 // child3 := 873 parent.AddNewChild(typ, "child1") 874 child2.AddNewChild(typ, "subchild1") 875 876 var buf bytes.Buffer 877 err := parent.WriteJSON(&buf, true) 878 if err != nil { 879 t.Error(err) 880 // } else { 881 // fmt.Printf("json output:\n%v\n", string(buf.Bytes())) 882 } 883 b := buf.Bytes() 884 885 tstload := NodeField2{} 886 tstload.InitName(&tstload, "") 887 err = tstload.ReadJSON(bytes.NewReader(b)) 888 if err != nil { 889 t.Error(err) 890 } else { 891 var buf2 bytes.Buffer 892 err = tstload.WriteJSON(&buf2, true) 893 if err != nil { 894 t.Error(err) 895 } 896 tstb := buf2.Bytes() 897 // fmt.Printf("test loaded json output: %v\n", string(tstb)) 898 if !bytes.Equal(tstb, b) { 899 t.Error("original and unmarshal'd json rep are not equivalent") 900 ioutil.WriteFile("/tmp/jsonout1", b, 0644) 901 ioutil.WriteFile("/tmp/jsonout2", tstb, 0644) 902 } 903 } 904 905 nwnd, err := ReadNewJSON(bytes.NewReader(b)) 906 if err != nil { 907 t.Error(err) 908 } else { 909 var buf2 bytes.Buffer 910 err = nwnd.WriteJSON(&buf2, true) 911 if err != nil { 912 t.Error(err) 913 } 914 tstb := buf2.Bytes() 915 // fmt.Printf("test loaded json output: %v\n", string(tstb)) 916 if !bytes.Equal(tstb, b) { 917 t.Error("original and unmarshal'd json rep are not equivalent") 918 } 919 } 920 } 921 922 func TestNodeFieldSet(t *testing.T) { 923 parent := NodeField2{} 924 parent.InitName(&parent, "par1") 925 typ := reflect.TypeOf(parent) 926 parent.Mbr1 = "bloop" 927 parent.Mbr2 = 32 928 // child1 := 929 parent.AddNewChild(typ, "child1") 930 child2 := parent.AddNewChild(typ, "child1").(*NodeField2) 931 // child3 := 932 parent.AddNewChild(typ, "child1") 933 child2.AddNewChild(typ, "subchild1") 934 935 ts := "child2 is nice" 936 err := child2.SetField("Mbr1", ts) 937 if err != nil { 938 t.Error(err) 939 } 940 fs := kit.NonPtrInterface(FieldByName(child2.This(), "Mbr1")) 941 if fs != ts { 942 t.Errorf("Set field error: %+v != %+v\n", fs, ts) 943 } 944 945 ts = "45.21" 946 err = child2.SetField("Mbr1", 45.21) 947 if err != nil { 948 t.Error(err) 949 } 950 fs = kit.NonPtrInterface(FieldByName(child2.This(), "Mbr1")) 951 if fs != ts { 952 t.Errorf("Set field error: %+v != %+v\n", fs, ts) 953 } 954 } 955 956 func TestClone(t *testing.T) { 957 parent := NodeField2{} 958 parent.InitName(&parent, "par1") 959 typ := reflect.TypeOf(parent) 960 parent.Mbr1 = "bloop" 961 parent.Mbr2 = 32 962 // child1 := 963 parent.AddNewChild(typ, "child1") 964 child2 := parent.AddNewChild(typ, "child1").(*NodeField2) 965 // child3 := 966 parent.AddNewChild(typ, "child1") 967 child2.AddNewChild(typ, "subchild1") 968 969 var buf bytes.Buffer 970 err := parent.WriteJSON(&buf, true) 971 if err != nil { 972 t.Error(err) 973 // } else { 974 // fmt.Printf("json output:\n%v\n", string(buf.Bytes())) 975 } 976 b := buf.Bytes() 977 978 tstload := parent.Clone() 979 var buf2 bytes.Buffer 980 err = tstload.WriteJSON(&buf2, true) 981 if err != nil { 982 t.Error(err) 983 } 984 tstb := buf2.Bytes() 985 // fmt.Printf("test loaded json output: %v\n", string(tstb)) 986 if !bytes.Equal(tstb, b) { 987 t.Error("original and unmarshal'd json rep are not equivalent") 988 ioutil.WriteFile("/tmp/jsonout1", b, 0644) 989 ioutil.WriteFile("/tmp/jsonout2", tstb, 0644) 990 } 991 } 992 993 // BuildGuiTreeSlow builds a tree that is typical of GUI structures where there are 994 // many widgets in a container and each widget has some number of parts. 995 // Uses slow AddChild method instead of fast one. 996 func BuildGuiTreeSlow(widgets, parts int, typ reflect.Type) Ki { 997 win := NewOfType(typ) 998 win.InitName(win, "window") 999 updt := win.UpdateStart() 1000 1001 vp := win.AddNewChild(typ, "vp") 1002 frame := vp.AddNewChild(typ, "frame") 1003 for wi := 0; wi < widgets; wi++ { 1004 widg := frame.AddNewChild(typ, fmt.Sprintf("widg_%d", wi)) 1005 1006 for pi := 0; pi < parts; pi++ { 1007 widg.AddNewChild(typ, fmt.Sprintf("part_%d", pi)) 1008 } 1009 } 1010 win.UpdateEnd(updt) 1011 return win 1012 } 1013 1014 // BuildGuiTree builds a tree that is typical of GUI structures where there are 1015 // many widgets in a container and each widget has some number of parts. 1016 func BuildGuiTree(widgets, parts int, typ reflect.Type) Ki { 1017 win := NewOfType(typ) 1018 win.InitName(win, "window") 1019 updt := win.UpdateStart() 1020 1021 vp := win.AddNewChild(typ, "vp") 1022 frame := vp.AddNewChild(typ, "frame") 1023 for wi := 0; wi < widgets; wi++ { 1024 widg := frame.AddNewChild(typ, fmt.Sprintf("widg_%d", wi)) 1025 1026 for pi := 0; pi < parts; pi++ { 1027 widg.AddNewChild(typ, fmt.Sprintf("part_%d", pi)) 1028 } 1029 } 1030 win.UpdateEnd(updt) 1031 return win 1032 } 1033 1034 var TotNodes int 1035 var TestGUITree_NodeEmbed Ki 1036 var TestGUITree_NodeField Ki 1037 var TestGUITree_NodeField2 Ki 1038 1039 var NWidgets = 10000 1040 var NParts = 5 1041 1042 func BenchmarkBuildGuiTree_NodeEmbed(b *testing.B) { 1043 for n := 0; n < b.N; n++ { 1044 wt := BuildGuiTree(NWidgets, NParts, KiT_NodeEmbed) 1045 TestGUITree_NodeEmbed = wt 1046 } 1047 } 1048 1049 func BenchmarkBuildGuiTree_NodeField(b *testing.B) { 1050 for n := 0; n < b.N; n++ { 1051 wt := BuildGuiTree(NWidgets, NParts, KiT_NodeField) 1052 TestGUITree_NodeField = wt 1053 } 1054 } 1055 1056 func BenchmarkBuildGuiTree_NodeField2(b *testing.B) { 1057 for n := 0; n < b.N; n++ { 1058 wt := BuildGuiTree(NWidgets, NParts, KiT_NodeField2) 1059 TestGUITree_NodeField2 = wt 1060 } 1061 } 1062 1063 func BenchmarkBuildGuiTreeSlow_NodeEmbed(b *testing.B) { 1064 // prof.Reset() 1065 // prof.Profiling = true 1066 for n := 0; n < b.N; n++ { 1067 wt := BuildGuiTreeSlow(NWidgets, NParts, KiT_NodeEmbed) 1068 TestGUITree_NodeEmbed = wt 1069 } 1070 // prof.Report(time.Millisecond) 1071 // prof.Profiling = false 1072 } 1073 1074 func BenchmarkFuncDownMeFirst_NodeEmbed(b *testing.B) { 1075 wt := TestGUITree_NodeEmbed 1076 nnodes := 0 1077 for n := 0; n < b.N; n++ { 1078 wt.FuncDownMeFirst(0, nil, func(k Ki, level int, d interface{}) bool { 1079 k.ClearFlag(int(Updating)) 1080 nnodes++ 1081 return Continue 1082 }) 1083 } 1084 TotNodes = nnodes 1085 // fmt.Printf("tot nodes: %d\n", TotNodes) 1086 } 1087 1088 func BenchmarkFuncDownMeFirst_NodeField(b *testing.B) { 1089 wt := TestGUITree_NodeField 1090 nnodes := 0 1091 for n := 0; n < b.N; n++ { 1092 wt.FuncDownMeFirst(0, nil, func(k Ki, level int, d interface{}) bool { 1093 k.ClearFlag(int(Updating)) 1094 nnodes++ 1095 return Continue 1096 }) 1097 } 1098 TotNodes = nnodes 1099 // fmt.Printf("tot nodes: %d\n", TotNodes) 1100 } 1101 1102 func BenchmarkFuncDownMeFirst_NodeField2(b *testing.B) { 1103 wt := TestGUITree_NodeField2 1104 nnodes := 0 1105 for n := 0; n < b.N; n++ { 1106 wt.FuncDownMeFirst(0, nil, func(k Ki, level int, d interface{}) bool { 1107 k.ClearFlag(int(Updating)) 1108 nnodes++ 1109 return Continue 1110 }) 1111 } 1112 TotNodes = nnodes 1113 // fmt.Printf("tot nodes: %d\n", TotNodes) 1114 }