go.ketch.com/lib/goja@v0.0.1/typedarrays_test.go (about)

     1  package goja
     2  
     3  import "testing"
     4  
     5  func TestUint16ArrayObject(t *testing.T) {
     6  	vm := New()
     7  	buf := vm._newArrayBuffer(vm.global.ArrayBufferPrototype, nil)
     8  	buf.data = make([]byte, 16)
     9  	if nativeEndian == littleEndian {
    10  		buf.data[2] = 0xFE
    11  		buf.data[3] = 0xCA
    12  	} else {
    13  		buf.data[2] = 0xCA
    14  		buf.data[3] = 0xFE
    15  	}
    16  	a := vm.newUint16ArrayObject(buf, 1, 1, nil)
    17  	v := a.getIdx(valueInt(0), nil)
    18  	if v != valueInt(0xCAFE) {
    19  		t.Fatalf("v: %v", v)
    20  	}
    21  }
    22  
    23  func TestArrayBufferGoWrapper(t *testing.T) {
    24  	vm := New()
    25  	data := []byte{0xAA, 0xBB}
    26  	buf := vm.NewArrayBuffer(data)
    27  	vm.Set("buf", buf)
    28  	_, err := vm.RunString(`
    29  	var a = new Uint8Array(buf);
    30  	if (a.length !== 2 || a[0] !== 0xAA || a[1] !== 0xBB) {
    31  		throw new Error(a);
    32  	}
    33  	`)
    34  	if err != nil {
    35  		t.Fatal(err)
    36  	}
    37  	ret, err := vm.RunString(`
    38  	var b = Uint8Array.of(0xCC, 0xDD);
    39  	b.buffer;
    40  	`)
    41  	if err != nil {
    42  		t.Fatal(err)
    43  	}
    44  	buf1 := ret.Export().(ArrayBuffer)
    45  	data1 := buf1.Bytes()
    46  	if len(data1) != 2 || data1[0] != 0xCC || data1[1] != 0xDD {
    47  		t.Fatal(data1)
    48  	}
    49  	if buf1.Detached() {
    50  		t.Fatal("buf1.Detached() returned true")
    51  	}
    52  	if !buf1.Detach() {
    53  		t.Fatal("buf1.Detach() returned false")
    54  	}
    55  	if !buf1.Detached() {
    56  		t.Fatal("buf1.Detached() returned false")
    57  	}
    58  	_, err = vm.RunString(`
    59  	if (b[0] !== undefined) {
    60  		throw new Error("b[0] !== undefined");
    61  	}
    62  	`)
    63  	if err != nil {
    64  		t.Fatal(err)
    65  	}
    66  }
    67  
    68  func TestTypedArrayIdx(t *testing.T) {
    69  	const SCRIPT = `
    70  	var a = new Uint8Array(1);
    71  
    72  	// 32-bit integer overflow, should not panic on 32-bit architectures
    73  	if (a[4294967297] !== undefined) {
    74  		throw new Error("4294967297");
    75  	}
    76  
    77  	// Canonical non-integer
    78  	a["Infinity"] = 8;
    79  	if (a["Infinity"] !== undefined) {
    80  		throw new Error("Infinity");
    81  	}
    82  	a["NaN"] = 1;
    83  	if (a["NaN"] !== undefined) {
    84  		throw new Error("NaN");
    85  	}
    86  
    87  	// Non-canonical integer
    88  	a["00"] = "00";
    89  	if (a["00"] !== "00") {
    90  		throw new Error("00");
    91  	}
    92  
    93  	// Non-canonical non-integer
    94  	a["1e-3"] = "1e-3";
    95  	if (a["1e-3"] !== "1e-3") {
    96  		throw new Error("1e-3");
    97  	}
    98  	if (a["0.001"] !== undefined) {
    99  		throw new Error("0.001");
   100  	}
   101  
   102  	// Negative zero
   103  	a["-0"] = 88;
   104  	if (a["-0"] !== undefined) {
   105  		throw new Error("-0");
   106  	}
   107  
   108  	if (a[0] !== 0) {
   109  		throw new Error("0");
   110  	}
   111  
   112  	a["9007199254740992"] = 1;
   113  	if (a["9007199254740992"] !== undefined) {
   114  		throw new Error("9007199254740992");
   115  	}
   116  	a["-9007199254740992"] = 1;
   117  	if (a["-9007199254740992"] !== undefined) {
   118  		throw new Error("-9007199254740992");
   119  	}
   120  
   121  	// Safe integer overflow, not canonical (Number("9007199254740993") === 9007199254740992)
   122  	a["9007199254740993"] = 1;
   123  	if (a["9007199254740993"] !== 1) {
   124  		throw new Error("9007199254740993");
   125  	}
   126  	a["-9007199254740993"] = 1;
   127  	if (a["-9007199254740993"] !== 1) {
   128  		throw new Error("-9007199254740993");
   129  	}
   130  
   131  	// Safe integer overflow, canonical Number("9007199254740994") == 9007199254740994
   132  	a["9007199254740994"] = 1;
   133  	if (a["9007199254740994"] !== undefined) {
   134  		throw new Error("9007199254740994");
   135  	}
   136  	a["-9007199254740994"] = 1;
   137  	if (a["-9007199254740994"] !== undefined) {
   138  		throw new Error("-9007199254740994");
   139  	}
   140  	`
   141  
   142  	testScript(SCRIPT, _undefined, t)
   143  }
   144  
   145  func TestTypedArraySetDetachedBuffer(t *testing.T) {
   146  	const SCRIPT = `
   147  	let sample = new Uint8Array([42]);
   148  	$DETACHBUFFER(sample.buffer);
   149  	sample[0] = 1;
   150  
   151  	assert.sameValue(sample[0], undefined, 'sample[0] = 1 is undefined');
   152  	sample['1.1'] = 1;
   153  	assert.sameValue(sample['1.1'], undefined, 'sample[\'1.1\'] = 1 is undefined');
   154  	sample['-0'] = 1;
   155  	assert.sameValue(sample['-0'], undefined, 'sample[\'-0\'] = 1 is undefined');
   156  	sample['-1'] = 1;
   157  	assert.sameValue(sample['-1'], undefined, 'sample[\'-1\'] = 1 is undefined');
   158  	sample['1'] = 1;
   159  	assert.sameValue(sample['1'], undefined, 'sample[\'1\'] = 1 is undefined');
   160  	sample['2'] = 1;
   161  	assert.sameValue(sample['2'], undefined, 'sample[\'2\'] = 1 is undefined');	
   162  	`
   163  	vm := New()
   164  	vm.Set("$DETACHBUFFER", func(buf *ArrayBuffer) {
   165  		buf.Detach()
   166  	})
   167  	vm.testScriptWithTestLib(SCRIPT, _undefined, t)
   168  }
   169  
   170  func TestTypedArrayDefinePropDetachedBuffer(t *testing.T) {
   171  	const SCRIPT = `
   172  	var desc = {
   173  	  value: 0,
   174  	  configurable: false,
   175  	  enumerable: true,
   176  	  writable: true
   177  	};
   178  	
   179  	var obj = {
   180  	  valueOf: function() {
   181  		throw new Error("valueOf() was called");
   182  	  }
   183  	};
   184  	let sample = new Uint8Array(42);
   185  	$DETACHBUFFER(sample.buffer);
   186  	
   187  	assert.sameValue(
   188  	Reflect.defineProperty(sample, "0", desc),
   189  	false,
   190  	'Reflect.defineProperty(sample, "0", {value: 0, configurable: false, enumerable: true, writable: true} ) must return false'
   191  	);
   192  	
   193  	assert.sameValue(
   194  	Reflect.defineProperty(sample, "-1", desc),
   195  	false,
   196  	'Reflect.defineProperty(sample, "-1", {value: 0, configurable: false, enumerable: true, writable: true} ) must return false'
   197  	);
   198  	
   199  	assert.sameValue(
   200  	Reflect.defineProperty(sample, "1.1", desc),
   201  	false,
   202  	'Reflect.defineProperty(sample, "1.1", {value: 0, configurable: false, enumerable: true, writable: true} ) must return false'
   203  	);
   204  	
   205  	assert.sameValue(
   206  	Reflect.defineProperty(sample, "-0", desc),
   207  	false,
   208  	'Reflect.defineProperty(sample, "-0", {value: 0, configurable: false, enumerable: true, writable: true} ) must return false'
   209  	);
   210  	
   211  	assert.sameValue(
   212  	Reflect.defineProperty(sample, "2", {
   213  	  configurable: true,
   214  	  enumerable: true,
   215  	  writable: true,
   216  	  value: obj
   217  	}),
   218  	false,
   219  	'Reflect.defineProperty(sample, "2", {configurable: true, enumerable: true, writable: true, value: obj}) must return false'
   220  	);
   221  	
   222  	assert.sameValue(
   223  	Reflect.defineProperty(sample, "3", {
   224  	  configurable: false,
   225  	  enumerable: false,
   226  	  writable: true,
   227  	  value: obj
   228  	}),
   229  	false,
   230  	'Reflect.defineProperty(sample, "3", {configurable: false, enumerable: false, writable: true, value: obj}) must return false'
   231  	);
   232  	
   233  	assert.sameValue(
   234  	Reflect.defineProperty(sample, "4", {
   235  	  writable: false,
   236  	  configurable: false,
   237  	  enumerable: true,
   238  	  value: obj
   239  	}),
   240  	false,
   241  	'Reflect.defineProperty("new TA(42)", "4", {writable: false, configurable: false, enumerable: true, value: obj}) must return false'
   242  	);
   243  	
   244  	assert.sameValue(
   245  	Reflect.defineProperty(sample, "42", desc),
   246  	false,
   247  	'Reflect.defineProperty(sample, "42", {value: 0, configurable: false, enumerable: true, writable: true} ) must return false'
   248  	);
   249  	
   250  	assert.sameValue(
   251  	Reflect.defineProperty(sample, "43", desc),
   252  	false,
   253  	'Reflect.defineProperty(sample, "43", {value: 0, configurable: false, enumerable: true, writable: true} ) must return false'
   254  	);
   255  	
   256  	assert.sameValue(
   257  	Reflect.defineProperty(sample, "5", {
   258  	  get: function() {}
   259  	}),
   260  	false,
   261  	'Reflect.defineProperty(sample, "5", {get: function() {}}) must return false'
   262  	);
   263  	
   264  	assert.sameValue(
   265  	Reflect.defineProperty(sample, "6", {
   266  	  configurable: false,
   267  	  enumerable: true,
   268  	  writable: true
   269  	}),
   270  	false,
   271  	'Reflect.defineProperty(sample, "6", {configurable: false, enumerable: true, writable: true}) must return false'
   272  	);
   273  	`
   274  	vm := New()
   275  	vm.Set("$DETACHBUFFER", func(buf *ArrayBuffer) {
   276  		buf.Detach()
   277  	})
   278  	vm.testScriptWithTestLib(SCRIPT, _undefined, t)
   279  }
   280  
   281  func TestTypedArrayDefineProperty(t *testing.T) {
   282  	const SCRIPT = `
   283  	var a = new Uint8Array(1);
   284  
   285  	assert.throws(TypeError, function() {
   286  		Object.defineProperty(a, "1", {value: 1});
   287  	});
   288  	assert.sameValue(Reflect.defineProperty(a, "1", {value: 1}), false, "1");
   289  
   290  	assert.throws(TypeError, function() {
   291  		Object.defineProperty(a, "Infinity", {value: 8});
   292  	});
   293  	assert.sameValue(Reflect.defineProperty(a, "Infinity", {value: 8}), false, "Infinity");
   294  
   295  	Object.defineProperty(a, "test", {value: "passed"});
   296  	assert.sameValue(a.test, "passed", "string property");
   297  
   298  	assert.throws(TypeError, function() {
   299  		Object.defineProperty(a, "0", {value: 1, writable: false});
   300  	}, "define non-writable");
   301  
   302  	assert.throws(TypeError, function() {
   303  		Object.defineProperty(a, "0", {get() { return 1; }});
   304  	}, "define accessor");
   305  
   306  	var sample = new Uint8Array([42, 42]);
   307  
   308  	assert.sameValue(
   309  	Reflect.defineProperty(sample, "0", {
   310  	  value: 8,
   311  	  configurable: true,
   312  	  enumerable: true,
   313  	  writable: true
   314  	}),
   315  	true
   316  	);
   317  
   318  	assert.sameValue(sample[0], 8, "property value was set");
   319  	let descriptor0 = Object.getOwnPropertyDescriptor(sample, "0");
   320  	assert.sameValue(descriptor0.value, 8);
   321  	assert.sameValue(descriptor0.configurable, true, "configurable");
   322  	assert.sameValue(descriptor0.enumerable, true);
   323  	assert.sameValue(descriptor0.writable, true);
   324  	`
   325  	testScriptWithTestLib(SCRIPT, _undefined, t)
   326  }
   327  
   328  func TestTypedArrayGetInvalidIndex(t *testing.T) {
   329  	const SCRIPT = `
   330  	var TypedArray = Object.getPrototypeOf(Int8Array);
   331  	var proto = TypedArray.prototype;
   332  	Object.defineProperty(proto, "1", {
   333  		get: function() {
   334  			throw new Error("OrdinaryGet was called!");
   335  		}
   336  	});
   337  	var a = new Uint8Array(1);
   338  	assert.sameValue(a[1], undefined);
   339  	assert.sameValue(a["1"], undefined);
   340  	`
   341  	testScriptWithTestLib(SCRIPT, _undefined, t)
   342  }