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 
22 using namespace testing;
23 using namespace testing::ext;
24 
25 namespace OHOS::Ace {
26 namespace {
27 constexpr double DEFAULT_DOUBLE0 = 0.0;
28 constexpr double DEFAULT_DOUBLE1 = 1.0;
29 constexpr double DEFAULT_DOUBLE2 = 2.0;
30 constexpr double DEFAULT_DOUBLE3 = 3.0;
31 
32 constexpr int32_t VALID_ROW0 = 0;
33 constexpr int32_t VALID_COL0 = 0;
34 constexpr int32_t VALID_ROW1 = 1;
35 constexpr int32_t VALID_COL1 = 1;
36 constexpr int32_t VALID_ROW2 = 2;
37 constexpr int32_t VALID_COL2 = 2;
38 constexpr uint32_t VALID_DIMENSION = 3;
39 
40 constexpr int32_t INVALID_ROW_NEG = -1;
41 constexpr int32_t INVALID_COL_NEG = -1;
42 constexpr int32_t INVALID_ROW_POS = 5;
43 constexpr int32_t INVALID_COL_POS = 5;
44 
45 constexpr uint32_t ROW_NUM = 4;
46 constexpr uint32_t COLUMN_NUM = 4;
47 } // namespace
48 
49 class 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  */
56 HWTEST_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  */
106 HWTEST_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  */
145 HWTEST_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  */
184 HWTEST_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  */
222 HWTEST_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  */
284 HWTEST_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  */
348 HWTEST_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  */
387 HWTEST_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