1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "ecmascript/global_env.h"
17#include "ecmascript/js_arraybuffer.h"
18#include "ecmascript/js_dataview.h"
19#include "ecmascript/object_factory.h"
20#include "ecmascript/tests/test_helper.h"
21
22using namespace panda::ecmascript;
23
24namespace panda::test {
25class JSDataViewTest :  public BaseTestWithScope<false> {
26};
27
28/*
29 * Feature: JSDataView
30 * Function: GetElementSize
31 * SubFunction: N/A
32 * FunctionPoints: Get ElementSize
33 * CaseDescription: Check whether the returned value through "GetElementSize" function is within expectations.
34 */
35HWTEST_F_L0(JSDataViewTest, GetElementSize)
36{
37    EXPECT_EQ(JSDataView::GetElementSize(DataViewType::INT8), 1U);
38    EXPECT_EQ(JSDataView::GetElementSize(DataViewType::UINT8), 1U);
39    EXPECT_EQ(JSDataView::GetElementSize(DataViewType::UINT8_CLAMPED), 1U);
40    EXPECT_EQ(JSDataView::GetElementSize(DataViewType::INT16), 2U);
41    EXPECT_EQ(JSDataView::GetElementSize(DataViewType::UINT16), 2U);
42    EXPECT_EQ(JSDataView::GetElementSize(DataViewType::INT32), 4U);
43    EXPECT_EQ(JSDataView::GetElementSize(DataViewType::UINT32), 4U);
44    EXPECT_EQ(JSDataView::GetElementSize(DataViewType::FLOAT32), 4U);
45    EXPECT_EQ(JSDataView::GetElementSize(DataViewType::FLOAT64), 8U);
46}
47
48/*
49 * Feature: JSDataView
50 * Function: SetDataView
51 * SubFunction: GetDataView
52 * FunctionPoints: Set DataView
53 * CaseDescription: Check whether the returned value through "GetDataView" function is within expectations after
54 *                  calling "SetDataView" function.
55 */
56HWTEST_F_L0(JSDataViewTest, SetDataView)
57{
58    EcmaVM *ecmaVMPtr = thread->GetEcmaVM();
59    ObjectFactory *factory = ecmaVMPtr->GetFactory();
60    JSHandle<GlobalEnv> handleGlobalEnv = ecmaVMPtr->GetGlobalEnv();
61
62    uint32_t lengthDataArrayBuf = 8;
63    uint32_t offsetDataView = 4;
64    uint32_t lengthDataView = 4;
65    JSHandle<JSFunction> handleFuncArrayBuf(handleGlobalEnv->GetArrayBufferFunction());
66    JSHandle<JSTaggedValue> handleTagValFuncArrayBuf(handleFuncArrayBuf);
67    JSHandle<JSArrayBuffer> handleArrayBuf(
68        factory->NewJSObjectByConstructor(handleFuncArrayBuf, handleTagValFuncArrayBuf));
69    handleArrayBuf->SetArrayBufferByteLength(lengthDataArrayBuf);
70
71    // Call "SetDataView" function through "NewJSDataView" function of "object_factory.cpp"
72    JSHandle<JSDataView> handleDataView = factory->NewJSDataView(handleArrayBuf, offsetDataView,
73        lengthDataView);
74    EXPECT_TRUE(handleDataView->GetDataView().IsTrue());
75
76    // Call "SetDataView" function in this HWTEST_F_L0.
77    handleDataView->SetDataView(thread, JSTaggedValue::False());
78    EXPECT_TRUE(handleDataView->GetDataView().IsFalse());
79    handleDataView->SetDataView(thread, JSTaggedValue::True());
80    EXPECT_TRUE(handleDataView->GetDataView().IsTrue());
81}
82
83/*
84 * Feature: JSDataView
85 * Function: SetViewedArrayBuffer
86 * SubFunction: GetViewedArrayBuffer
87 * FunctionPoints: Set ViewedArrayBuffer
88 * CaseDescription: Check whether the returned value through "GetViewedArrayBuffer" function is within expectations
89 *                  after calling "SetViewedArrayBuffer" function.
90 */
91HWTEST_F_L0(JSDataViewTest, SetViewedArrayBuffer)
92{
93    EcmaVM *ecmaVMPtr = thread->GetEcmaVM();
94    ObjectFactory *factory = ecmaVMPtr->GetFactory();
95    JSHandle<JSFunction> handleFuncArrayBuf(ecmaVMPtr->GetGlobalEnv()->GetArrayBufferFunction());
96    JSHandle<JSTaggedValue> handleTagValFuncArrayBuf(handleFuncArrayBuf);
97
98    uint32_t lengthDataArrayBuf1 = 8;
99    uint32_t lengthDataArrayBuf2 = 16;
100    uint32_t offsetDataView = 4;
101    uint32_t lengthDataView = 4;
102    JSHandle<JSArrayBuffer> handleArrayBuf1(
103        factory->NewJSObjectByConstructor(handleFuncArrayBuf, handleTagValFuncArrayBuf));
104    JSHandle<JSArrayBuffer> handleArrayBuf2(
105        factory->NewJSObjectByConstructor(handleFuncArrayBuf, handleTagValFuncArrayBuf));
106    handleArrayBuf1->SetArrayBufferByteLength(lengthDataArrayBuf1);
107    handleArrayBuf2->SetArrayBufferByteLength(lengthDataArrayBuf2);
108
109    // Call "SetViewedArrayBuffer" function through "NewJSDataView" function of "object_factory.cpp"
110    JSHandle<JSDataView> handleDataView = factory->NewJSDataView(handleArrayBuf1, offsetDataView,
111        lengthDataView);
112    JSHandle<JSTaggedValue> handleTagValDataViewFrom1(thread, handleArrayBuf1.GetTaggedValue());
113    JSHandle<JSTaggedValue> handleTagValDataViewTo1(thread, handleDataView->GetViewedArrayBuffer());
114    EXPECT_TRUE(JSTaggedValue::Equal(thread, handleTagValDataViewFrom1, handleTagValDataViewTo1));
115
116    // Call "SetViewedArrayBuffer" function in this HWTEST_F_L0.
117    handleDataView->SetViewedArrayBuffer(thread, handleArrayBuf2.GetTaggedValue());
118    JSHandle<JSTaggedValue> handleTagValDataViewFrom2(thread, handleArrayBuf2.GetTaggedValue());
119    JSHandle<JSTaggedValue> handleTagValDataViewTo2(thread, handleDataView->GetViewedArrayBuffer());
120    EXPECT_TRUE(JSTaggedValue::Equal(thread, handleTagValDataViewFrom2, handleTagValDataViewTo2));
121    EXPECT_FALSE(JSTaggedValue::Equal(thread, handleTagValDataViewFrom1, handleTagValDataViewFrom2));
122}
123
124/*
125 * Feature: JSDataView
126 * Function: SetByteLength
127 * SubFunction: GetByteLength
128 * FunctionPoints: Set ByteLength
129 * CaseDescription: Check whether the returned value through "GetByteLength" function is within expectations after
130 *                  calling "SetByteLength" function.
131 */
132HWTEST_F_L0(JSDataViewTest, SetByteLength)
133{
134    EcmaVM *ecmaVMPtr = thread->GetEcmaVM();
135    ObjectFactory *factory = ecmaVMPtr->GetFactory();
136    JSHandle<JSFunction> handleFuncArrayBuf(ecmaVMPtr->GetGlobalEnv()->GetArrayBufferFunction());
137    JSHandle<JSTaggedValue> handleTagValFuncArrayBuf(handleFuncArrayBuf);
138
139    uint32_t lengthDataArrayBuf = 8;
140    uint32_t offsetDataView = 4;
141    uint32_t lengthDataView1 = 4;
142    uint32_t lengthDataView2 = 2;
143    JSHandle<JSArrayBuffer> handleArrayBuf(
144        factory->NewJSObjectByConstructor(handleFuncArrayBuf, handleTagValFuncArrayBuf));
145    handleArrayBuf->SetArrayBufferByteLength(lengthDataArrayBuf);
146
147    // Call "SetByteLength" function through "NewJSDataView" function of "object_factory.cpp"
148    JSHandle<JSDataView> handleDataView = factory->NewJSDataView(handleArrayBuf, offsetDataView,
149        lengthDataView1);
150    EXPECT_EQ(handleDataView->GetByteLength(), lengthDataView1);
151
152    // Call "SetByteLength" function in this HWTEST_F_L0.
153    handleDataView->SetByteLength(lengthDataView2);
154    EXPECT_EQ(handleDataView->GetByteLength(), lengthDataView2);
155}
156
157/*
158 * Feature: JSDataView
159 * Function: SetByteOffset
160 * SubFunction: GetByteOffset
161 * FunctionPoints: Set ByteOffset
162 * CaseDescription: Check whether the returned value through "GetByteOffset" function is within expectations after
163 *                  calling "SetByteOffset" function.
164 */
165HWTEST_F_L0(JSDataViewTest, SetByteOffset)
166{
167    EcmaVM *ecmaVMPtr = thread->GetEcmaVM();
168    ObjectFactory *factory = ecmaVMPtr->GetFactory();
169    JSHandle<JSFunction> handleFuncArrayBuf1(ecmaVMPtr->GetGlobalEnv()->GetArrayBufferFunction());
170    JSHandle<JSTaggedValue> handleTagValFuncArrayBuf1(handleFuncArrayBuf1);
171
172    uint32_t lengthDataArrayBuf = 8;
173    uint32_t offsetDataView1 = 4;
174    uint32_t offsetDataView2 = 6;
175    uint32_t lengthDataView = 2;
176    JSHandle<JSArrayBuffer> handleArrayBuf(
177        factory->NewJSObjectByConstructor(handleFuncArrayBuf1, handleTagValFuncArrayBuf1));
178    handleArrayBuf->SetArrayBufferByteLength(lengthDataArrayBuf);
179
180    // Call "SetByteOffset" function through "NewJSDataView" function of "object_factory.cpp"
181    JSHandle<JSDataView> handleDataView = factory->NewJSDataView(handleArrayBuf, offsetDataView1,
182        lengthDataView);
183    EXPECT_EQ(handleDataView->GetByteOffset(), offsetDataView1);
184
185    // Call "SetByteOffset" function in this HWTEST_F_L0.
186    handleDataView->SetByteOffset(offsetDataView2);
187    EXPECT_EQ(handleDataView->GetByteOffset(), offsetDataView2);
188}
189}  // namespace panda::test
190