@@ -467,7 +467,7 @@ func TestCallWithNull(t *testing.T) {
467
467
func TestReflection (t * testing.T ) {
468
468
o := js .Global .Call ("eval" , "({ answer: 42 })" )
469
469
if reflect .ValueOf (o ).Interface ().(* js.Object ) != o {
470
- t .Fail ()
470
+ t .Fatal ()
471
471
}
472
472
473
473
type S struct {
@@ -477,18 +477,19 @@ func TestReflection(t *testing.T) {
477
477
478
478
v := reflect .ValueOf (& s ).Elem ()
479
479
if v .Field (0 ).Interface ().(* js.Object ).Get ("answer" ).Int () != 42 {
480
- t .Fail ()
480
+ t .Fatal ()
481
481
}
482
482
if v .Field (0 ).MethodByName ("Get" ).Call ([]reflect.Value {reflect .ValueOf ("answer" )})[0 ].Interface ().(* js.Object ).Int () != 42 {
483
- t .Fail ()
483
+ t .Fatal ()
484
484
}
485
485
v .Field (0 ).Set (reflect .ValueOf (js .Global .Call ("eval" , "({ answer: 100 })" )))
486
486
if s .Field .Get ("answer" ).Int () != 100 {
487
- t .Fail ()
487
+ t .Fatal ()
488
488
}
489
489
490
- if fmt .Sprintf ("%+v" , s ) != "{Field:[object Object]}" {
491
- t .Fail ()
490
+ expFmt := "{Field:[object Object]}"
491
+ if v := fmt .Sprintf ("%+v" , s ); v != expFmt {
492
+ t .Fatalf ("fmt out was: %q; expected %q" , v , expFmt )
492
493
}
493
494
}
494
495
@@ -571,3 +572,219 @@ func TestUint8Array(t *testing.T) {
571
572
t .Errorf ("Non-empty byte array is not externalized as a Uint8Array" )
572
573
}
573
574
}
575
+
576
+ type Internalize struct {
577
+ * js.Object
578
+
579
+ string string `js:"string"`
580
+ bool bool `js:"bool"`
581
+ }
582
+
583
+ func TestInternalizeString (t * testing.T ) {
584
+ fieldName := "string"
585
+ zero := ""
586
+
587
+ s := & Internalize {Object : js .Global .Get ("Object" ).New ()}
588
+
589
+ // *************
590
+ // undefined
591
+ // *************
592
+ s .Object .Set (fieldName , jsundefined ())
593
+
594
+ // via struct field
595
+ if v := s .string ; v != zero {
596
+ t .Fatalf ("expected string field to be %q, got %q" , zero , v )
597
+ }
598
+
599
+ // via *js.Object.String()
600
+ if v := s .Object .Get (fieldName ).String (); v != zero {
601
+ t .Fatalf ("expected string field via *js.Object.String() to be %q, got %q" , zero , v )
602
+ }
603
+
604
+ // *************
605
+ // null
606
+ // *************
607
+ s .Object .Set (fieldName , jsnull ())
608
+
609
+ // via struct field
610
+ if v := s .string ; v != zero {
611
+ t .Fatalf ("expected string field to be %q, got %q" , zero , v )
612
+ }
613
+
614
+ // via *js.Object.String()
615
+ if v := s .Object .Get (fieldName ).String (); v != zero {
616
+ t .Fatalf ("expected string field via *js.Object.String() to be %q, got %q" , zero , v )
617
+ }
618
+
619
+ // *************
620
+ // valid primitive string
621
+ // *************
622
+ exp := "ok"
623
+ s .Object .Set (fieldName , jsval (`"` + exp + `"` ))
624
+
625
+ // via struct field
626
+ if v := s .string ; v != exp {
627
+ t .Fatalf ("expected string field to be %q, got %q" , zero , v )
628
+ }
629
+
630
+ // via *js.Object.String()
631
+ if v := s .Object .Get (fieldName ).String (); v != exp {
632
+ t .Fatalf ("expected string field via *js.Object.String() to be %q, got %q" , zero , v )
633
+ }
634
+
635
+ // *************
636
+ // valid String object
637
+ // *************
638
+ s .Object .Set (fieldName , jsval (`new String("` + exp + `")` ))
639
+
640
+ // via struct field
641
+ if v := s .string ; v != exp {
642
+ t .Fatalf ("expected string field to be %q, got %q" , zero , v )
643
+ }
644
+
645
+ // via *js.Object.String()
646
+ if v := s .Object .Get (fieldName ).String (); v != exp {
647
+ t .Fatalf ("expected string field via *js.Object.String() to be %q, got %q" , zero , v )
648
+ }
649
+
650
+ // *************
651
+ // invalid
652
+ // *************
653
+ s .Object .Set (fieldName , jsval ("5" ))
654
+
655
+ shouldRuntimePanic (t , "runtime error: tried to internalize non-string value of type number" , func () {
656
+ _ = s .string
657
+ })
658
+
659
+ shouldRuntimePanic (t , "runtime error: tried to internalize non-string value of type number" , func () {
660
+ _ = s .Object .Get (fieldName ).String ()
661
+ })
662
+ }
663
+
664
+ func TestInternalizeBool (t * testing.T ) {
665
+ fieldName := "bool"
666
+ zero := false
667
+
668
+ s := & Internalize {Object : js .Global .Get ("Object" ).New ()}
669
+
670
+ // *************
671
+ // undefined
672
+ // *************
673
+ s .Object .Set (fieldName , jsundefined ())
674
+
675
+ // via struct field
676
+ if v := s .bool ; v != zero {
677
+ t .Fatalf ("expected bool field to be %q, got %q" , zero , v )
678
+ }
679
+
680
+ // via *js.Object.Bool()
681
+ if v := s .Object .Get (fieldName ).Bool (); v != zero {
682
+ t .Fatalf ("expected bool field via *js.Object.Bool() to be %q, got %q" , zero , v )
683
+ }
684
+
685
+ // *************
686
+ // null
687
+ // *************
688
+ s .Object .Set (fieldName , jsnull ())
689
+
690
+ // via struct field
691
+ if v := s .bool ; v != zero {
692
+ t .Fatalf ("expected bool field to be %q, got %q" , zero , v )
693
+ }
694
+
695
+ // via *js.Object.Bool()
696
+ if v := s .Object .Get (fieldName ).Bool (); v != zero {
697
+ t .Fatalf ("expected bool field via *js.Object.Bool() to be %q, got %q" , zero , v )
698
+ }
699
+
700
+ // *************
701
+ // valid primitive bool
702
+ // *************
703
+ exp := true
704
+ s .Object .Set (fieldName , jsval (`true` ))
705
+
706
+ // via struct field
707
+ if v := s .bool ; v != exp {
708
+ t .Fatalf ("expected bool field to be %v, got %v" , exp , v )
709
+ }
710
+
711
+ // via *js.Object.Bool()
712
+ if v := s .Object .Get (fieldName ).Bool (); v != exp {
713
+ t .Fatalf ("expected bool field via *js.Object.Bool() to be %q, got %q" , zero , v )
714
+ }
715
+
716
+ // *************
717
+ // valid Bool object
718
+ // *************
719
+ s .Object .Set (fieldName , jsval (`new Boolean(true)` ))
720
+
721
+ // via struct field
722
+ if v := s .bool ; v != exp {
723
+ t .Fatalf ("expected bool field to be %q, got %q" , zero , v )
724
+ }
725
+
726
+ // via *js.Object.Bool()
727
+ if v := s .Object .Get (fieldName ).Bool (); v != exp {
728
+ t .Fatalf ("expected bool field via *js.Object.Bool() to be %q, got %q" , zero , v )
729
+ }
730
+
731
+ // *************
732
+ // invalid
733
+ // *************
734
+ s .Object .Set (fieldName , jsval ("5" ))
735
+
736
+ shouldRuntimePanic (t , "runtime error: tried to internalize non-bool value of type number" , func () {
737
+ _ = s .bool
738
+ })
739
+
740
+ shouldRuntimePanic (t , "runtime error: tried to internalize non-bool value of type number" , func () {
741
+ _ = s .Object .Get (fieldName ).Bool ()
742
+ })
743
+ }
744
+
745
+ func jsval (v string ) * js.Object {
746
+ return js .Global .Call ("eval" , v )
747
+ }
748
+
749
+ func jsnull () * js.Object {
750
+ return js .Global .Call ("eval" , "null" )
751
+ }
752
+
753
+ func jsundefined () * js.Object {
754
+ return js .Global .Call ("eval" , "undefined" )
755
+ }
756
+
757
+ func consolelog (args ... interface {}) {
758
+ js .Global .Get ("console" ).Call ("log" , args ... )
759
+ }
760
+
761
+ func shouldRuntimePanic (t * testing.T , msg string , f func ()) {
762
+ defer func () {
763
+ err , ok := recover ().(error )
764
+ if ! ok {
765
+ t .Fatalf ("expected to have had to handle panic; we didn't see a panic" )
766
+ }
767
+
768
+ if err .Error () != msg {
769
+ t .Fatalf ("expected error %q, got %q" , msg , err )
770
+ }
771
+ }()
772
+
773
+ f ()
774
+ }
775
+
776
+ // |----------------+-------------------------+---------------+--------|
777
+ // | Go target type | Javascript source value | Translation | Result |
778
+ // |----------------+-------------------------+---------------+--------|
779
+ // | string | null | UTF16 -> UTF8 | "" |
780
+ // | | undefined | | "" |
781
+ // | | "" | | "" |
782
+ // | | new String("") | | "" |
783
+ // | | "ok" † | | "ok" |
784
+ // | | new String("ok") † | | "ok" |
785
+ // |----------------+-------------------------+---------------+--------|
786
+ // | bool | null | none | false |
787
+ // | | undefined | | false |
788
+ // | | false † | | false |
789
+ // | | new Boolean(false) † | | false |
790
+ // |----------------+-------------------------+---------------+--------|
0 commit comments