...

Source file src/github.com/dop251/goja/builtin_json_test.go

Documentation: github.com/dop251/goja

     1  package goja
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"strings"
     7  	"testing"
     8  	"time"
     9  )
    10  
    11  func TestJSONMarshalObject(t *testing.T) {
    12  	vm := New()
    13  	o := vm.NewObject()
    14  	o.Set("test", 42)
    15  	o.Set("testfunc", vm.Get("Error"))
    16  	b, err := json.Marshal(o)
    17  	if err != nil {
    18  		t.Fatal(err)
    19  	}
    20  	if string(b) != `{"test":42}` {
    21  		t.Fatalf("Unexpected value: %s", b)
    22  	}
    23  }
    24  
    25  func TestJSONMarshalGoDate(t *testing.T) {
    26  	vm := New()
    27  	o := vm.NewObject()
    28  	o.Set("test", time.Unix(86400, 0).UTC())
    29  	b, err := json.Marshal(o)
    30  	if err != nil {
    31  		t.Fatal(err)
    32  	}
    33  	if string(b) != `{"test":"1970-01-02T00:00:00Z"}` {
    34  		t.Fatalf("Unexpected value: %s", b)
    35  	}
    36  }
    37  
    38  func TestJSONMarshalObjectCircular(t *testing.T) {
    39  	vm := New()
    40  	o := vm.NewObject()
    41  	o.Set("o", o)
    42  	_, err := json.Marshal(o)
    43  	if err == nil {
    44  		t.Fatal("Expected error")
    45  	}
    46  	if !strings.HasSuffix(err.Error(), "Converting circular structure to JSON") {
    47  		t.Fatalf("Unexpected error: %v", err)
    48  	}
    49  }
    50  
    51  func TestJSONStringifyCircularWrappedGo(t *testing.T) {
    52  	type CircularType struct {
    53  		Self *CircularType
    54  	}
    55  	vm := New()
    56  	v := CircularType{}
    57  	v.Self = &v
    58  	vm.Set("v", &v)
    59  	_, err := vm.RunString("JSON.stringify(v)")
    60  	if err == nil {
    61  		t.Fatal("Expected error")
    62  	}
    63  	if !strings.HasPrefix(err.Error(), "TypeError: Converting circular structure to JSON") {
    64  		t.Fatalf("Unexpected error: %v", err)
    65  	}
    66  }
    67  
    68  func TestJSONParseReviver(t *testing.T) {
    69  	// example from
    70  	// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse
    71  	const SCRIPT = `
    72  	JSON.parse('{"p": 5}', function(key, value) {
    73  	  return typeof value === 'number'
    74          ? value * 2 // return value * 2 for numbers
    75  	    : value     // return everything else unchanged
    76  	 })["p"]
    77  	`
    78  
    79  	testScript(SCRIPT, intToValue(10), t)
    80  }
    81  
    82  func TestQuoteMalformedSurrogatePair(t *testing.T) {
    83  	testScript(`JSON.stringify("\uD800")`, asciiString(`"\ud800"`), t)
    84  }
    85  
    86  func TestEOFWrapping(t *testing.T) {
    87  	vm := New()
    88  
    89  	_, err := vm.RunString("JSON.parse('{')")
    90  	if err == nil {
    91  		t.Fatal("Expected error")
    92  	}
    93  
    94  	if !strings.Contains(err.Error(), "Unexpected end of JSON input") {
    95  		t.Fatalf("Error doesn't contain human-friendly wrapper: %v", err)
    96  	}
    97  }
    98  
    99  type testMarshalJSONErrorStruct struct {
   100  	e error
   101  }
   102  
   103  func (s *testMarshalJSONErrorStruct) MarshalJSON() ([]byte, error) {
   104  	return nil, s.e
   105  }
   106  
   107  func TestMarshalJSONError(t *testing.T) {
   108  	vm := New()
   109  	v := testMarshalJSONErrorStruct{e: errors.New("test error")}
   110  	vm.Set("v", &v)
   111  	_, err := vm.RunString("JSON.stringify(v)")
   112  	if !errors.Is(err, v.e) {
   113  		t.Fatalf("Unexpected error: %v", err)
   114  	}
   115  }
   116  
   117  func BenchmarkJSONStringify(b *testing.B) {
   118  	b.StopTimer()
   119  	vm := New()
   120  	var createObj func(level int) *Object
   121  	createObj = func(level int) *Object {
   122  		o := vm.NewObject()
   123  		o.Set("field1", "test")
   124  		o.Set("field2", 42)
   125  		if level > 0 {
   126  			level--
   127  			o.Set("obj1", createObj(level))
   128  			o.Set("obj2", createObj(level))
   129  		}
   130  		return o
   131  	}
   132  
   133  	o := createObj(3)
   134  	json := vm.Get("JSON").(*Object)
   135  	stringify, _ := AssertFunction(json.Get("stringify"))
   136  	b.StartTimer()
   137  	for i := 0; i < b.N; i++ {
   138  		stringify(nil, o)
   139  	}
   140  }
   141  

View as plain text