11cb0ef41Sopenharmony_ci#include "aliased_buffer-inl.h"
21cb0ef41Sopenharmony_ci#include "node_test_fixture.h"
31cb0ef41Sopenharmony_ci#include "v8.h"
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciusing node::AliasedBufferBase;
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ciclass AliasBufferTest : public NodeTestFixture {};
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_citemplate <class NativeT>
101cb0ef41Sopenharmony_civoid CreateOracleValues(std::vector<NativeT>* buf) {
111cb0ef41Sopenharmony_ci  for (size_t i = 0, j = buf->size(); i < buf->size(); i++, j--) {
121cb0ef41Sopenharmony_ci    (*buf)[i] = static_cast<NativeT>(j);
131cb0ef41Sopenharmony_ci  }
141cb0ef41Sopenharmony_ci}
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_citemplate <class NativeT, class V8T>
171cb0ef41Sopenharmony_civoid WriteViaOperator(AliasedBufferBase<NativeT, V8T>* aliasedBuffer,
181cb0ef41Sopenharmony_ci                      const std::vector<NativeT>& oracle) {
191cb0ef41Sopenharmony_ci  // write through the API
201cb0ef41Sopenharmony_ci  for (size_t i = 0; i < oracle.size(); i++) {
211cb0ef41Sopenharmony_ci    (*aliasedBuffer)[i] = oracle[i];
221cb0ef41Sopenharmony_ci  }
231cb0ef41Sopenharmony_ci}
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_citemplate <class NativeT, class V8T>
261cb0ef41Sopenharmony_civoid WriteViaSetValue(AliasedBufferBase<NativeT, V8T>* aliasedBuffer,
271cb0ef41Sopenharmony_ci                      const std::vector<NativeT>& oracle) {
281cb0ef41Sopenharmony_ci  // write through the API
291cb0ef41Sopenharmony_ci  for (size_t i = 0; i < oracle.size(); i++) {
301cb0ef41Sopenharmony_ci    aliasedBuffer->SetValue(i, oracle[i]);
311cb0ef41Sopenharmony_ci  }
321cb0ef41Sopenharmony_ci}
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_citemplate <class NativeT, class V8T>
351cb0ef41Sopenharmony_civoid ReadAndValidate(v8::Isolate* isolate,
361cb0ef41Sopenharmony_ci                     v8::Local<v8::Context> context,
371cb0ef41Sopenharmony_ci                     AliasedBufferBase<NativeT, V8T>* aliasedBuffer,
381cb0ef41Sopenharmony_ci                     const std::vector<NativeT>& oracle) {
391cb0ef41Sopenharmony_ci  // read through the API
401cb0ef41Sopenharmony_ci  for (size_t i = 0; i < oracle.size(); i++) {
411cb0ef41Sopenharmony_ci    NativeT v1 = (*aliasedBuffer)[i];
421cb0ef41Sopenharmony_ci    NativeT v2 = aliasedBuffer->GetValue(i);
431cb0ef41Sopenharmony_ci    EXPECT_TRUE(v1 == oracle[i]);
441cb0ef41Sopenharmony_ci    EXPECT_TRUE(v2 == oracle[i]);
451cb0ef41Sopenharmony_ci  }
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci  // validate size of JS Buffer
481cb0ef41Sopenharmony_ci  EXPECT_TRUE(aliasedBuffer->GetJSArray()->Length() == oracle.size());
491cb0ef41Sopenharmony_ci  EXPECT_TRUE(
501cb0ef41Sopenharmony_ci    aliasedBuffer->GetJSArray()->ByteLength() ==
511cb0ef41Sopenharmony_ci    (oracle.size() * sizeof(NativeT)));
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci  // validate operator * and GetBuffer are the same
541cb0ef41Sopenharmony_ci  EXPECT_TRUE(aliasedBuffer->GetNativeBuffer() == *(*aliasedBuffer));
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci  // read through the JS API
571cb0ef41Sopenharmony_ci  for (size_t i = 0; i < oracle.size(); i++) {
581cb0ef41Sopenharmony_ci    v8::Local<V8T> v8TypedArray = aliasedBuffer->GetJSArray();
591cb0ef41Sopenharmony_ci    v8::MaybeLocal<v8::Value> v = v8TypedArray->Get(context, i);
601cb0ef41Sopenharmony_ci    EXPECT_TRUE(v.IsEmpty() == false);
611cb0ef41Sopenharmony_ci    v8::Local<v8::Value> v2 = v.ToLocalChecked();
621cb0ef41Sopenharmony_ci    EXPECT_TRUE(v2->IsNumber());
631cb0ef41Sopenharmony_ci    v8::MaybeLocal<v8::Number> v3 = v2->ToNumber(context);
641cb0ef41Sopenharmony_ci    v8::Local<v8::Number> v4 = v3.ToLocalChecked();
651cb0ef41Sopenharmony_ci    NativeT actualValue = static_cast<NativeT>(v4->Value());
661cb0ef41Sopenharmony_ci    EXPECT_TRUE(actualValue == oracle[i]);
671cb0ef41Sopenharmony_ci  }
681cb0ef41Sopenharmony_ci}
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_citemplate <class NativeT, class V8T>
711cb0ef41Sopenharmony_civoid ReadWriteTest(v8::Isolate* isolate) {
721cb0ef41Sopenharmony_ci  v8::Isolate::Scope isolate_scope(isolate);
731cb0ef41Sopenharmony_ci  v8::HandleScope handle_scope(isolate);
741cb0ef41Sopenharmony_ci  v8::Local<v8::Context> context = v8::Context::New(isolate);
751cb0ef41Sopenharmony_ci  v8::Context::Scope context_scope(context);
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci  const size_t size = 100;
781cb0ef41Sopenharmony_ci  AliasedBufferBase<NativeT, V8T> ab(isolate, size);
791cb0ef41Sopenharmony_ci  std::vector<NativeT> oracle(size);
801cb0ef41Sopenharmony_ci  CreateOracleValues(&oracle);
811cb0ef41Sopenharmony_ci  WriteViaOperator(&ab, oracle);
821cb0ef41Sopenharmony_ci  ReadAndValidate(isolate, context, &ab, oracle);
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci  WriteViaSetValue(&ab, oracle);
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ci  // validate copy constructor
871cb0ef41Sopenharmony_ci  {
881cb0ef41Sopenharmony_ci    AliasedBufferBase<NativeT, V8T> ab2(ab);
891cb0ef41Sopenharmony_ci    ReadAndValidate(isolate, context, &ab2, oracle);
901cb0ef41Sopenharmony_ci  }
911cb0ef41Sopenharmony_ci  ReadAndValidate(isolate, context, &ab, oracle);
921cb0ef41Sopenharmony_ci}
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_citemplate <
951cb0ef41Sopenharmony_ci    class NativeT_A, class V8T_A,
961cb0ef41Sopenharmony_ci    class NativeT_B, class V8T_B,
971cb0ef41Sopenharmony_ci    class NativeT_C, class V8T_C>
981cb0ef41Sopenharmony_civoid SharedBufferTest(
991cb0ef41Sopenharmony_ci    v8::Isolate* isolate,
1001cb0ef41Sopenharmony_ci    size_t count_A,
1011cb0ef41Sopenharmony_ci    size_t count_B,
1021cb0ef41Sopenharmony_ci    size_t count_C) {
1031cb0ef41Sopenharmony_ci  v8::Isolate::Scope isolate_scope(isolate);
1041cb0ef41Sopenharmony_ci  v8::HandleScope handle_scope(isolate);
1051cb0ef41Sopenharmony_ci  v8::Local<v8::Context> context = v8::Context::New(isolate);
1061cb0ef41Sopenharmony_ci  v8::Context::Scope context_scope(context);
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ci  size_t sizeInBytes_A = count_A * sizeof(NativeT_A);
1091cb0ef41Sopenharmony_ci  size_t sizeInBytes_B = count_B * sizeof(NativeT_B);
1101cb0ef41Sopenharmony_ci  size_t sizeInBytes_C = count_C * sizeof(NativeT_C);
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_ci  AliasedBufferBase<uint8_t, v8::Uint8Array> rootBuffer(
1131cb0ef41Sopenharmony_ci      isolate, sizeInBytes_A + sizeInBytes_B + sizeInBytes_C);
1141cb0ef41Sopenharmony_ci  AliasedBufferBase<NativeT_A, V8T_A> ab_A(isolate, 0, count_A, rootBuffer);
1151cb0ef41Sopenharmony_ci  AliasedBufferBase<NativeT_B, V8T_B> ab_B(
1161cb0ef41Sopenharmony_ci      isolate, sizeInBytes_A, count_B, rootBuffer);
1171cb0ef41Sopenharmony_ci  AliasedBufferBase<NativeT_C, V8T_C> ab_C(
1181cb0ef41Sopenharmony_ci      isolate, sizeInBytes_A + sizeInBytes_B, count_C, rootBuffer);
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci  std::vector<NativeT_A> oracle_A(count_A);
1211cb0ef41Sopenharmony_ci  std::vector<NativeT_B> oracle_B(count_B);
1221cb0ef41Sopenharmony_ci  std::vector<NativeT_C> oracle_C(count_C);
1231cb0ef41Sopenharmony_ci  CreateOracleValues(&oracle_A);
1241cb0ef41Sopenharmony_ci  CreateOracleValues(&oracle_B);
1251cb0ef41Sopenharmony_ci  CreateOracleValues(&oracle_C);
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ci  WriteViaOperator(&ab_A, oracle_A);
1281cb0ef41Sopenharmony_ci  WriteViaOperator(&ab_B, oracle_B);
1291cb0ef41Sopenharmony_ci  WriteViaOperator(&ab_C, oracle_C);
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_ci  ReadAndValidate(isolate, context, &ab_A, oracle_A);
1321cb0ef41Sopenharmony_ci  ReadAndValidate(isolate, context, &ab_B, oracle_B);
1331cb0ef41Sopenharmony_ci  ReadAndValidate(isolate, context, &ab_C, oracle_C);
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ci  WriteViaSetValue(&ab_A, oracle_A);
1361cb0ef41Sopenharmony_ci  WriteViaSetValue(&ab_B, oracle_B);
1371cb0ef41Sopenharmony_ci  WriteViaSetValue(&ab_C, oracle_C);
1381cb0ef41Sopenharmony_ci
1391cb0ef41Sopenharmony_ci  ReadAndValidate(isolate, context, &ab_A, oracle_A);
1401cb0ef41Sopenharmony_ci  ReadAndValidate(isolate, context, &ab_B, oracle_B);
1411cb0ef41Sopenharmony_ci  ReadAndValidate(isolate, context, &ab_C, oracle_C);
1421cb0ef41Sopenharmony_ci}
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, Uint8Array) {
1451cb0ef41Sopenharmony_ci  ReadWriteTest<uint8_t, v8::Uint8Array>(isolate_);
1461cb0ef41Sopenharmony_ci}
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, Int8Array) {
1491cb0ef41Sopenharmony_ci  ReadWriteTest<int8_t, v8::Int8Array>(isolate_);
1501cb0ef41Sopenharmony_ci}
1511cb0ef41Sopenharmony_ci
1521cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, Uint16Array) {
1531cb0ef41Sopenharmony_ci  ReadWriteTest<uint16_t, v8::Uint16Array>(isolate_);
1541cb0ef41Sopenharmony_ci}
1551cb0ef41Sopenharmony_ci
1561cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, Int16Array) {
1571cb0ef41Sopenharmony_ci  ReadWriteTest<int16_t, v8::Int16Array>(isolate_);
1581cb0ef41Sopenharmony_ci}
1591cb0ef41Sopenharmony_ci
1601cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, Uint32Array) {
1611cb0ef41Sopenharmony_ci  ReadWriteTest<uint32_t, v8::Uint32Array>(isolate_);
1621cb0ef41Sopenharmony_ci}
1631cb0ef41Sopenharmony_ci
1641cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, Int32Array) {
1651cb0ef41Sopenharmony_ci  ReadWriteTest<int32_t, v8::Int32Array>(isolate_);
1661cb0ef41Sopenharmony_ci}
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, Float32Array) {
1691cb0ef41Sopenharmony_ci  ReadWriteTest<float, v8::Float32Array>(isolate_);
1701cb0ef41Sopenharmony_ci}
1711cb0ef41Sopenharmony_ci
1721cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, Float64Array) {
1731cb0ef41Sopenharmony_ci  ReadWriteTest<double, v8::Float64Array>(isolate_);
1741cb0ef41Sopenharmony_ci}
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, SharedArrayBuffer1) {
1771cb0ef41Sopenharmony_ci  SharedBufferTest<
1781cb0ef41Sopenharmony_ci      uint32_t, v8::Uint32Array,
1791cb0ef41Sopenharmony_ci      double, v8::Float64Array,
1801cb0ef41Sopenharmony_ci      int8_t, v8::Int8Array>(isolate_, 100, 80, 8);
1811cb0ef41Sopenharmony_ci}
1821cb0ef41Sopenharmony_ci
1831cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, SharedArrayBuffer2) {
1841cb0ef41Sopenharmony_ci  SharedBufferTest<
1851cb0ef41Sopenharmony_ci      double, v8::Float64Array,
1861cb0ef41Sopenharmony_ci      int8_t, v8::Int8Array,
1871cb0ef41Sopenharmony_ci      double, v8::Float64Array>(isolate_, 100, 8, 8);
1881cb0ef41Sopenharmony_ci}
1891cb0ef41Sopenharmony_ci
1901cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, SharedArrayBuffer3) {
1911cb0ef41Sopenharmony_ci  SharedBufferTest<
1921cb0ef41Sopenharmony_ci      int8_t, v8::Int8Array,
1931cb0ef41Sopenharmony_ci      int8_t, v8::Int8Array,
1941cb0ef41Sopenharmony_ci      double, v8::Float64Array>(isolate_, 1, 7, 8);
1951cb0ef41Sopenharmony_ci}
1961cb0ef41Sopenharmony_ci
1971cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, SharedArrayBuffer4) {
1981cb0ef41Sopenharmony_ci  SharedBufferTest<
1991cb0ef41Sopenharmony_ci      int8_t, v8::Int8Array,
2001cb0ef41Sopenharmony_ci      int8_t, v8::Int8Array,
2011cb0ef41Sopenharmony_ci      int32_t, v8::Int32Array>(isolate_, 1, 3, 1);
2021cb0ef41Sopenharmony_ci}
2031cb0ef41Sopenharmony_ci
2041cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, OperatorOverloads) {
2051cb0ef41Sopenharmony_ci  v8::Isolate::Scope isolate_scope(isolate_);
2061cb0ef41Sopenharmony_ci  v8::HandleScope handle_scope(isolate_);
2071cb0ef41Sopenharmony_ci  v8::Local<v8::Context> context = v8::Context::New(isolate_);
2081cb0ef41Sopenharmony_ci  v8::Context::Scope context_scope(context);
2091cb0ef41Sopenharmony_ci  const size_t size = 10;
2101cb0ef41Sopenharmony_ci  AliasedBufferBase<uint32_t, v8::Uint32Array> ab{isolate_, size};
2111cb0ef41Sopenharmony_ci
2121cb0ef41Sopenharmony_ci  EXPECT_EQ(static_cast<uint32_t>(1), ab[0] = 1);
2131cb0ef41Sopenharmony_ci  EXPECT_EQ(static_cast<uint32_t>(4), ab[0] += 3);
2141cb0ef41Sopenharmony_ci  EXPECT_EQ(static_cast<uint32_t>(2), ab[0] -= 2);
2151cb0ef41Sopenharmony_ci  EXPECT_EQ(static_cast<uint32_t>(-2), -ab[0]);
2161cb0ef41Sopenharmony_ci}
2171cb0ef41Sopenharmony_ci
2181cb0ef41Sopenharmony_ciTEST_F(AliasBufferTest, OperatorOverloadsRefs) {
2191cb0ef41Sopenharmony_ci  v8::Isolate::Scope isolate_scope(isolate_);
2201cb0ef41Sopenharmony_ci  v8::HandleScope handle_scope(isolate_);
2211cb0ef41Sopenharmony_ci  v8::Local<v8::Context> context = v8::Context::New(isolate_);
2221cb0ef41Sopenharmony_ci  v8::Context::Scope context_scope(context);
2231cb0ef41Sopenharmony_ci  AliasedBufferBase<uint32_t, v8::Uint32Array> ab{isolate_, 2};
2241cb0ef41Sopenharmony_ci  using Reference = AliasedBufferBase<uint32_t, v8::Uint32Array>::Reference;
2251cb0ef41Sopenharmony_ci  Reference ref = ab[0];
2261cb0ef41Sopenharmony_ci  Reference ref_value = ab[1] = 2;
2271cb0ef41Sopenharmony_ci
2281cb0ef41Sopenharmony_ci  EXPECT_EQ(static_cast<uint32_t>(2), ref = ref_value);
2291cb0ef41Sopenharmony_ci  EXPECT_EQ(static_cast<uint32_t>(4), ref += ref_value);
2301cb0ef41Sopenharmony_ci  EXPECT_EQ(static_cast<uint32_t>(2), ref -= ref_value);
2311cb0ef41Sopenharmony_ci  EXPECT_EQ(static_cast<uint32_t>(-2), -ref);
2321cb0ef41Sopenharmony_ci}
233