1/*
2 * Copyright (c) 2022 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 <cmath>
17
18#include "gtest/gtest.h"
19
20#include "base/geometry/matrix3.h"
21
22using namespace testing;
23using namespace testing::ext;
24
25namespace OHOS::Ace {
26namespace {
27constexpr double DEFAULT_DOUBLE0 = 0.0;
28constexpr double DEFAULT_DOUBLE1 = 1.0;
29constexpr double DEFAULT_DOUBLE2 = 2.0;
30constexpr double DEFAULT_DOUBLE3 = 3.0;
31
32constexpr int32_t VALID_ROW0 = 0;
33constexpr int32_t VALID_COL0 = 0;
34constexpr int32_t VALID_ROW1 = 1;
35constexpr int32_t VALID_COL1 = 1;
36constexpr int32_t VALID_ROW2 = 2;
37constexpr int32_t VALID_COL2 = 2;
38constexpr uint32_t VALID_DIMENSION = 3;
39
40constexpr int32_t INVALID_ROW_NEG = -1;
41constexpr int32_t INVALID_COL_NEG = -1;
42constexpr int32_t INVALID_ROW_POS = 5;
43constexpr int32_t INVALID_COL_POS = 5;
44
45constexpr uint32_t ROW_NUM = 4;
46constexpr uint32_t COLUMN_NUM = 4;
47} // namespace
48
49class Matrix3Test : public testing::Test {};
50
51/**
52 * @tc.name: Matrix3Test001
53 * @tc.desc: Test the function SetEntry of the classes Matrix3, Matrix3N and MatrixN3.
54 * @tc.type: FUNC
55 */
56HWTEST_F(Matrix3Test, Matrix3Test001, TestSize.Level1)
57{
58    /**
59     * @tc.steps1: initialize parameters.
60     */
61    Matrix3 matrixObj1;
62    std::string initStrObj1 = matrixObj1.ToString();
63    Matrix3N matrix3NObj1(COLUMN_NUM);
64    std::string initStr3NObj1 = matrix3NObj1.ToString();
65    MatrixN3 matrixN3Obj1(ROW_NUM);
66    std::string initStrN3Obj1 = matrixN3Obj1.ToString();
67
68    /**
69     * @tc.steps2: Call the function SetEntry of the classes Matrix3.
70     * @tc.expected: Set the value of a legal location, the value of the corresponding location changes normally.
71     *               Set the value of an illegal location, there is no change.
72     */
73    matrixObj1.SetEntry(INVALID_ROW_NEG, INVALID_COL_NEG, DEFAULT_DOUBLE1);
74    EXPECT_EQ(matrixObj1.ToString(), initStrObj1);
75    matrixObj1.SetEntry(INVALID_ROW_POS, INVALID_COL_POS, DEFAULT_DOUBLE1);
76    EXPECT_EQ(matrixObj1.ToString(), initStrObj1);
77    matrixObj1.SetEntry(VALID_ROW0, VALID_COL0, DEFAULT_DOUBLE1);
78    EXPECT_DOUBLE_EQ(matrixObj1[VALID_ROW0][VALID_COL0], DEFAULT_DOUBLE1);
79
80    /**
81     * @tc.steps3: Call the function SetEntry of the classes Matrix3N.
82     * @tc.expected: Set the value of a legal location, the value of the corresponding location changes normally.
83     *               Set the value of an illegal location, there is no change.
84     */
85    matrix3NObj1.SetEntry(INVALID_ROW_POS, INVALID_COL_POS, DEFAULT_DOUBLE1);
86    EXPECT_EQ(matrix3NObj1.ToString(), initStr3NObj1);
87    matrix3NObj1.SetEntry(VALID_ROW0, VALID_COL0, DEFAULT_DOUBLE1);
88    EXPECT_DOUBLE_EQ(matrix3NObj1[VALID_ROW0][VALID_COL0], DEFAULT_DOUBLE1);
89
90    /**
91     * @tc.steps4: Call the function SetEntry of the classes MatrixN3.
92     * @tc.expected: Set the value of a legal location, the value of the corresponding location changes normally.
93     *               Set the value of an illegal location, there is no change.
94     */
95    matrixN3Obj1.SetEntry(INVALID_ROW_POS, INVALID_COL_POS, DEFAULT_DOUBLE1);
96    EXPECT_EQ(matrixN3Obj1.ToString(), initStrN3Obj1);
97    matrixN3Obj1.SetEntry(VALID_ROW0, VALID_COL0, DEFAULT_DOUBLE1);
98    EXPECT_DOUBLE_EQ(matrixN3Obj1[VALID_ROW0][VALID_COL0], DEFAULT_DOUBLE1);
99}
100
101/**
102 * @tc.name: Matrix3Test002
103 * @tc.desc: Test the function Transpose of the classes Matrix3, Matrix3N and MatrixN3.
104 * @tc.type: FUNC
105 */
106HWTEST_F(Matrix3Test, Matrix3Test002, TestSize.Level1)
107{
108    /**
109     * @tc.steps1: initialize parameters.
110     */
111    Matrix3 matrixObj1;
112    matrixObj1.SetEntry(VALID_ROW0, VALID_COL2, DEFAULT_DOUBLE1);
113    Matrix3N matrix3NObj1(COLUMN_NUM);
114    matrix3NObj1.SetEntry(VALID_ROW0, VALID_COL2, DEFAULT_DOUBLE1);
115    MatrixN3 matrixN3Obj1(ROW_NUM);
116    matrixN3Obj1.SetEntry(VALID_ROW0, VALID_COL2, DEFAULT_DOUBLE1);
117
118    /**
119     * @tc.steps2: Call the function Transpose of the classes Matrix3.
120     * @tc.expected: The value of corresponding locations of two matrixes is equal.
121     */
122    Matrix3 matrixObj2 = matrixObj1.Transpose();
123    EXPECT_DOUBLE_EQ(matrixObj2[VALID_ROW2][VALID_COL0], DEFAULT_DOUBLE1);
124
125    /**
126     * @tc.steps3: Call the function Transpose of the classes Matrix3N.
127     * @tc.expected: The value of corresponding locations of two matrixes is equal.
128     */
129    MatrixN3 matrixN3Obj2 = matrix3NObj1.Transpose();
130    EXPECT_DOUBLE_EQ(matrixN3Obj2[VALID_ROW2][VALID_COL0], DEFAULT_DOUBLE1);
131
132    /**
133     * @tc.steps4: Call the function Transpose of the classes MatrixN3.
134     * @tc.expected: The value of corresponding locations of two matrixes is equal.
135     */
136    Matrix3N matrix3NObj2 = matrixN3Obj1.Transpose();
137    EXPECT_DOUBLE_EQ(matrix3NObj2[VALID_ROW2][VALID_COL0], DEFAULT_DOUBLE1);
138}
139
140/**
141 * @tc.name: Matrix3Test003
142 * @tc.desc: Test the function inverse of the class Matrix3.
143 * @tc.type: FUNC
144 */
145HWTEST_F(Matrix3Test, Matrix3Test003, TestSize.Level1)
146{
147    /**
148     * @tc.steps1: initialize parameters.
149     */
150    Matrix3 matrixObj1;
151    matrixObj1.SetEntry(VALID_ROW0, VALID_COL0, DEFAULT_DOUBLE1);
152    Matrix3 matrixObj2;
153    std::string initStrObj2 = matrixObj2.ToString();
154
155    /**
156     * @tc.steps2: Call the function inverse of the matrix with determinant 0.
157     * @tc.expected: The function inverse does not work, and the matrix matrixObj2 is not changed.
158     */
159    EXPECT_FALSE(matrixObj1.Invert(matrixObj2));
160    EXPECT_EQ(matrixObj2.ToString(), initStrObj2);
161
162    /**
163     * @tc.steps3: Set the matrix matrixObj1 to identity matrix.
164     */
165    matrixObj1.SetEntry(VALID_ROW1, VALID_COL1, DEFAULT_DOUBLE1);
166    matrixObj1.SetEntry(VALID_ROW2, VALID_COL2, DEFAULT_DOUBLE1);
167
168    /**
169     * @tc.steps4: Call the function inverse of the identity matrix.
170     * @tc.expected: The inverse matrix of matrixObj2 is the identity matrix, and is set to the matrix matrixObj2.
171     */
172    EXPECT_TRUE(matrixObj1.Invert(matrixObj2));
173    EXPECT_NE(matrixObj2.ToString(), initStrObj2);
174    EXPECT_DOUBLE_EQ(matrixObj2[VALID_ROW0][VALID_COL0], DEFAULT_DOUBLE1);
175    EXPECT_DOUBLE_EQ(matrixObj2[VALID_ROW1][VALID_COL1], DEFAULT_DOUBLE1);
176    EXPECT_DOUBLE_EQ(matrixObj2[VALID_ROW2][VALID_COL2], DEFAULT_DOUBLE1);
177}
178
179/**
180 * @tc.name: Matrix3Test004
181 * @tc.desc: Test the function operator* of classes Matrix3 and Matrix3N.
182 * @tc.type: FUNC
183 */
184HWTEST_F(Matrix3Test, Matrix3Test004, TestSize.Level1)
185{
186    /**
187     * @tc.steps1: initialize parameters.
188     */
189    Matrix3 matrixObj1;
190    matrixObj1.SetEntry(VALID_ROW0, VALID_COL0, DEFAULT_DOUBLE1);
191    matrixObj1.SetEntry(VALID_ROW1, VALID_COL1, DEFAULT_DOUBLE1);
192    matrixObj1.SetEntry(VALID_ROW2, VALID_COL2, DEFAULT_DOUBLE1);
193    Matrix3N matrix3NObj1(COLUMN_NUM);
194    matrix3NObj1.SetEntry(VALID_ROW0, VALID_COL0, DEFAULT_DOUBLE1);
195    matrix3NObj1.SetEntry(VALID_ROW1, VALID_COL1, DEFAULT_DOUBLE2);
196    matrix3NObj1.SetEntry(VALID_ROW2, VALID_COL2, DEFAULT_DOUBLE3);
197    MatrixN3 matrixN3Obj1(ROW_NUM);
198    matrixN3Obj1.SetEntry(VALID_ROW0, VALID_COL0, DEFAULT_DOUBLE1);
199    matrixN3Obj1.SetEntry(VALID_ROW1, VALID_COL1, 1.0 / DEFAULT_DOUBLE2);
200    matrixN3Obj1.SetEntry(VALID_ROW2, VALID_COL2, 1.0 / DEFAULT_DOUBLE3);
201
202    /**
203     * @tc.steps2:  Call the function operator* of classes Matrix3 with the identity matrix matrixObj1.
204     * @tc.expected: The product of matrixes matrixObj1 and matrix3NObj1 is equal to matrix3NObj2.
205     */
206    Matrix3N matrix3NObj2 = matrixObj1 * matrix3NObj1;
207    EXPECT_EQ(matrix3NObj1.ToString(), matrix3NObj2.ToString());
208
209    /**
210     * @tc.steps3:  Call the function operator* of classes Matrix3N.
211     * @tc.expected: The product of matrixes matrix3NObj1 and matrixN3Obj1 is equal to matrixObj1.
212     */
213    Matrix3 matrixObj2 = matrix3NObj1 * matrixN3Obj1;
214    EXPECT_EQ(matrixObj2.ToString(), matrixObj1.ToString());
215}
216
217/**
218 * @tc.name: Matrix3Test005
219 * @tc.desc: Test the function MapScalars of the class Matrix3.
220 * @tc.type: FUNC
221 */
222HWTEST_F(Matrix3Test, Matrix3Test005, TestSize.Level1)
223{
224    /**
225     * @tc.steps1: initialize parameters.
226     */
227    Matrix3 matrixObj1;
228    matrixObj1.SetEntry(VALID_ROW0, VALID_COL0, DEFAULT_DOUBLE1);
229    matrixObj1.SetEntry(VALID_ROW1, VALID_COL1, DEFAULT_DOUBLE2);
230    matrixObj1.SetEntry(VALID_ROW2, VALID_COL2, DEFAULT_DOUBLE3);
231
232    /**
233     * @tc.steps2: Given the vector srcVec whose size is invalid, test the
234     *            function MapScalars with single parameter.
235     * @tc.expected: The function MapScalars does not work and all values of the return vector are equal to zero.
236     */
237    std::vector<double> srcVec = { DEFAULT_DOUBLE1, DEFAULT_DOUBLE1 };
238    std::vector<double> dstVec = matrixObj1.MapScalars(srcVec);
239    EXPECT_EQ(dstVec.size(), VALID_DIMENSION);
240    EXPECT_EQ(dstVec[0], DEFAULT_DOUBLE0);
241    EXPECT_EQ(dstVec[1], DEFAULT_DOUBLE0);
242    EXPECT_EQ(dstVec[2], DEFAULT_DOUBLE0);
243
244    /**
245     * @tc.steps3: Given the vector srcVec whose size is valid, test the
246     *            function MapScalars with single parameter.
247     * @tc.expected: The values of return vector is equal to values on the diagonal of matrixObj1.
248     */
249    srcVec.push_back(DEFAULT_DOUBLE1);
250    dstVec = matrixObj1.MapScalars(srcVec);
251    EXPECT_EQ(dstVec[0], DEFAULT_DOUBLE1);
252    EXPECT_EQ(dstVec[1], DEFAULT_DOUBLE2);
253    EXPECT_EQ(dstVec[2], DEFAULT_DOUBLE3);
254
255    /**
256     * @tc.steps4: Given the vector srcVec whose size is invalid, test the
257     *            function MapScalars with two parameters.
258     * @tc.expected: The function MapScalars does not work and the return vector is empty.
259     */
260    srcVec.clear();
261    dstVec.clear();
262    srcVec.push_back(DEFAULT_DOUBLE1);
263    srcVec.push_back(DEFAULT_DOUBLE1);
264    EXPECT_FALSE(matrixObj1.MapScalars(srcVec, dstVec));
265    EXPECT_TRUE(dstVec.empty());
266
267    /**
268     * @tc.steps5: Given the vector srcVec whose size is valid, test the
269     *            function MapScalars with two parameters.
270     * @tc.expected: The values of return vector is equal to values on the diagonal of matrixObj1.
271     */
272    srcVec.push_back(DEFAULT_DOUBLE1);
273    EXPECT_TRUE(matrixObj1.MapScalars(srcVec, dstVec));
274    EXPECT_EQ(dstVec[0], DEFAULT_DOUBLE1);
275    EXPECT_EQ(dstVec[1], DEFAULT_DOUBLE2);
276    EXPECT_EQ(dstVec[2], DEFAULT_DOUBLE3);
277}
278
279/**
280 * @tc.name: Matrix3Test006
281 * @tc.desc: Test the function MapScalars of the class Matrix3N.
282 * @tc.type: FUNC
283 */
284HWTEST_F(Matrix3Test, Matrix3Test006, TestSize.Level1)
285{
286    /**
287     * @tc.steps1: initialize parameters.
288     */
289    Matrix3N matrix3NObj1(COLUMN_NUM);
290    matrix3NObj1.SetEntry(VALID_ROW0, VALID_COL0, DEFAULT_DOUBLE1);
291    matrix3NObj1.SetEntry(VALID_ROW1, VALID_COL1, DEFAULT_DOUBLE2);
292    matrix3NObj1.SetEntry(VALID_ROW2, VALID_COL2, DEFAULT_DOUBLE3);
293
294    /**
295     * @tc.steps2: Given the vector srcVec whose size is invalid, test the
296     *            function MapScalars with single parameter.
297     * @tc.expected: The function MapScalars does not work and all values of the return vector are equal to zero.
298     */
299    std::vector<double> srcVec = { DEFAULT_DOUBLE1, DEFAULT_DOUBLE1 };
300    std::vector<double> dstVec = matrix3NObj1.MapScalars(srcVec);
301    EXPECT_EQ(dstVec.size(), VALID_DIMENSION);
302    EXPECT_EQ(dstVec[0], DEFAULT_DOUBLE0);
303    EXPECT_EQ(dstVec[1], DEFAULT_DOUBLE0);
304    EXPECT_EQ(dstVec[2], DEFAULT_DOUBLE0);
305
306    /**
307     * @tc.steps3: Given the vector srcVec whose size is valid, test the
308     *            function MapScalars with single parameter.
309     * @tc.expected: The values of return vector is equal to values on the diagonal of matrix3NObj1.
310     */
311    srcVec.push_back(DEFAULT_DOUBLE1);
312    srcVec.push_back(DEFAULT_DOUBLE1);
313    dstVec = matrix3NObj1.MapScalars(srcVec);
314    EXPECT_EQ(dstVec[0], DEFAULT_DOUBLE1);
315    EXPECT_EQ(dstVec[1], DEFAULT_DOUBLE2);
316    EXPECT_EQ(dstVec[2], DEFAULT_DOUBLE3);
317
318    /**
319     * @tc.steps4: Given the vector srcVec whose size is invalid, test the
320     *            function MapScalars with two parameters.
321     * @tc.expected: The function MapScalars does not work and the return vector is empty.
322     */
323    srcVec.clear();
324    dstVec.clear();
325    srcVec.push_back(DEFAULT_DOUBLE1);
326    srcVec.push_back(DEFAULT_DOUBLE1);
327    EXPECT_FALSE(matrix3NObj1.MapScalars(srcVec, dstVec));
328    EXPECT_TRUE(dstVec.empty());
329
330    /**
331     * @tc.steps: Given the vector srcVec whose size is valid, test the
332     *            function MapScalars with two parameters.
333     * @tc.expected: The values of return vector is equal to values on the diagonal of matrix3NObj1.
334     */
335    srcVec.push_back(DEFAULT_DOUBLE1);
336    srcVec.push_back(DEFAULT_DOUBLE1);
337    EXPECT_TRUE(matrix3NObj1.MapScalars(srcVec, dstVec));
338    EXPECT_EQ(dstVec[0], DEFAULT_DOUBLE1);
339    EXPECT_EQ(dstVec[1], DEFAULT_DOUBLE2);
340    EXPECT_EQ(dstVec[2], DEFAULT_DOUBLE3);
341}
342
343/**
344 * @tc.name: Matrix3Test007
345 * @tc.desc: Test the function MapScalars of the class MatrixN3.
346 * @tc.type: FUNC
347 */
348HWTEST_F(Matrix3Test, Matrix3Test007, TestSize.Level1)
349{
350    /**
351     * @tc.steps1: initialize parameters.
352     */
353    MatrixN3 matrixN3Obj1(ROW_NUM);
354    matrixN3Obj1.SetEntry(VALID_ROW0, VALID_COL0, DEFAULT_DOUBLE1);
355    matrixN3Obj1.SetEntry(VALID_ROW1, VALID_COL1, DEFAULT_DOUBLE2);
356    matrixN3Obj1.SetEntry(VALID_ROW2, VALID_COL2, DEFAULT_DOUBLE3);
357
358    /**
359     * @tc.steps2: Given the vector srcVec whose size is invalid, test the function MapScalars.
360     * @tc.expected: The function MapScalars does not work and all values of the return vector are equal to zero.
361     */
362    std::vector<double> srcVec = { DEFAULT_DOUBLE1, DEFAULT_DOUBLE1 };
363    std::vector<double> dstVec = matrixN3Obj1.MapScalars(srcVec);
364    EXPECT_EQ(dstVec.size(), ROW_NUM);
365    EXPECT_EQ(dstVec[0], DEFAULT_DOUBLE0);
366    EXPECT_EQ(dstVec[1], DEFAULT_DOUBLE0);
367    EXPECT_EQ(dstVec[2], DEFAULT_DOUBLE0);
368    EXPECT_EQ(dstVec[3], DEFAULT_DOUBLE0);
369
370    /**
371     * @tc.steps3: Given the vector srcVec whose size is valid, test the function MapScalars.
372     * @tc.expected: The values of return vector is equal to values on the diagonal of matrixN3Obj1.
373     */
374    srcVec.push_back(DEFAULT_DOUBLE1);
375    dstVec = matrixN3Obj1.MapScalars(srcVec);
376    EXPECT_EQ(dstVec[0], DEFAULT_DOUBLE1);
377    EXPECT_EQ(dstVec[1], DEFAULT_DOUBLE2);
378    EXPECT_EQ(dstVec[2], DEFAULT_DOUBLE3);
379    EXPECT_EQ(dstVec[3], DEFAULT_DOUBLE0);
380}
381
382/**
383 * @tc.name: Matrix3Test008
384 * @tc.desc: Test the function SetEntry for Matrix3/Matrix3N
385 * @tc.type: FUNC
386 */
387HWTEST_F(Matrix3Test, Matrix3Test008, TestSize.Level1)
388{
389    /**
390     * @tc.steps1: initialize parameters.Matrix3::SetEntry: index out of range
391     */
392    Matrix3 matrixObj1;
393    // true false false false
394    matrixObj1.SetEntry(-1, 2, 5.0f);
395    // false true false false
396    matrixObj1.SetEntry(10, 2, 5.0f);
397    // false false true false
398    matrixObj1.SetEntry(0, -1, 5.0f);
399    // false false false true
400    matrixObj1.SetEntry(0, 10, 5.0f);
401    // false false false false
402    matrixObj1.SetEntry(0, 2, 5.0f);
403    EXPECT_EQ(matrixObj1(0, 2) == 5.0f, true);
404
405    /**
406     * @tc.steps2: Matrix3N::SetEntry: index out of range
407     */
408    Matrix3N matrix3NObj1(3);
409    // true false
410    bool ret = matrix3NObj1.SetEntry(10, 2, 5.0f);
411    EXPECT_FALSE(ret);
412    // false true
413    bool ret2 = matrix3NObj1.SetEntry(0, 3, 5.0f);
414    EXPECT_FALSE(ret2);
415    // false false
416    bool ret3 = matrix3NObj1.SetEntry(0, 2, 5.0f);
417    EXPECT_TRUE(ret3);
418
419    /**
420     * @tc.steps3: MatrixN3::SetEntry: index out of range
421     */
422    MatrixN3 matrixN3Obj1(3);
423    // true false
424    bool ret4 = matrixN3Obj1.SetEntry(3, 2, 5.0f);
425    EXPECT_FALSE(ret4);
426    // false true
427    bool ret5 = matrixN3Obj1.SetEntry(0, 10, 5.0f);
428    EXPECT_FALSE(ret5);
429    // false false
430    bool ret6 = matrixN3Obj1.SetEntry(0, 2, 5.0f);
431    EXPECT_TRUE(ret6);
432
433    // Matrix3N::operator*: matrix size not match
434    MatrixN3 matrixN3Obj2(2);
435    Matrix3 ret7 = matrix3NObj1 * matrixN3Obj2;
436    EXPECT_EQ(ret7(0, 0) == 0.0f, true);
437}
438} // namespace OHOS::Ace
439