Fixed typos
[platform/core/csapi/opentk.git] / tests / OpenTK.Tests.Math / QuaternionTests.cs
1 using Xunit;
2 using System;
3 using System.Collections.Generic;
4
5 namespace OpenTK.Tests.Math
6 {
7         /// <summary>
8         /// Generates Quaternion test data.
9         /// </summary>
10         public class QuaternionTestDataGenerator
11         {
12                 /// <summary>
13                 /// Returns the single axis test cases.
14                 /// 1. param: rotation in euler angles
15                 /// 2. param: expected result of xyz-component of quaternion
16                 /// 3. param: test name (Don't found a working way how to pass this to xUnit runner). I let it here for test documentation
17                 /// </summary>
18                 /// <value>The single axis test cases.</value>
19                 public static IEnumerable<object> SingleAxisTestCases()
20                 {
21                         yield return new object[] { new Vector3(1, 0, 0), Vector3.UnitX, "Rotate around x axis" };
22                         yield return new object[] { new Vector3(0, 1, 0), Vector3.UnitY, "Rotate around y axis" };
23                         yield return new object[] { new Vector3(0, 0, 1), Vector3.UnitZ, "Rotate around z axis" };
24                 }
25
26                 /// <summary>
27                 /// Returns the single ToAxisAngle test cases.
28                 /// 1. param: Quaternion which a definied value of xyz-component.
29                 /// 2. param: expected result of xyz-component of quaternion
30                 /// 3. param: test name (Don't found a working way how to pass this to xUnit runner). I let it here for test documentation
31                 /// </summary>
32                 /// <value>The single axis test cases.</value>
33                 public static IEnumerable<object[]> ToAxisAngleTestCases()
34                 {
35                         yield return new object[] { new Quaternion(Vector3.UnitX, 0), Vector3.UnitX, "Rotate around x axis" };
36                         yield return new object[] { new Quaternion(Vector3.UnitY, 0), Vector3.UnitY, "Rotate around y axis" };
37                         yield return new object[] { new Quaternion(Vector3.UnitZ, 0), Vector3.UnitZ, "Rotate around z axis" };
38                 }
39         }
40
41         /// <summary>
42         /// Provides some methods which helps to verify test results
43         /// </summary>
44         internal static class QuaternionTestHelper
45         {
46                 /// <summary>
47                 /// Verifies the direction of an given <see cref="Vector3"/>.
48                 /// </summary>
49                 /// <returns>false: When <paramref name="toTest"/> does contain xyz values, when it should be 0,
50                 /// or does not contain 0 when it should be</returns>
51                 /// <param name="toTest">To test</param>
52                 /// <param name="expected">Expected directions. Values getting only 0 checked</param>
53                 public static bool VerifyEqualSingleDirection(Vector3 toTest, Vector3 expected)
54                 {
55                         //To verify the direction of an vector, just respect the 0 values and check against these.
56                         //The length of the vectors are ignored.
57                         if (expected.X == 0)
58                         {
59                                 if (toTest.X != 0)
60                                         return false;
61                         }
62                         else
63                         {
64                                 if (toTest.X == 0)
65                                         return false;
66                         }
67
68                         if (expected.Y == 0)
69                         {
70                                 if (toTest.Y != 0)
71                                         return false;
72                         }
73                         else
74                         {
75                                 if (toTest.Y == 0)
76                                         return false;
77                         }
78
79                         if (expected.Z == 0)
80                         {
81                                 if (toTest.Z != 0)
82                                         return false;
83                         }
84                         else
85                         {
86                                 if (toTest.Z == 0)
87                                         return false;
88                         }
89
90                         return true;
91                 }
92         }
93
94         public class Quaternion_Tests
95         {
96                 /// <summary>
97                 /// Checks if a single given value (either pitch, yaw or roll) get converted into correct x,y,z value of quaternion.
98                 /// </summary>
99                 /// <param name="eulerValues">euler angle values</param>
100                 /// <param name="expectedResult">expected xyz component of quaternion</param>
101                 /// <param name="testName">Taken from nUnit test data. Don't know how to name data driven tests for xUnit which actually works.</param>
102                 [Theory]
103                 [MemberData(nameof(QuaternionTestDataGenerator.SingleAxisTestCases), MemberType = typeof(QuaternionTestDataGenerator))]
104                 public void CtorEulerAnglesFloat_SingleEulerAngleSet_RotateCorrectAxis(Vector3 eulerValues, Vector3 expectedResult, String testName)
105                 {
106                         //Arrange + Act: Create Quaternion with "pitch/yaw/roll"
107                         var cut = new Quaternion(eulerValues.X, eulerValues.Y, eulerValues.Z);
108
109                         //Assert: Use helper, to check if part of the two correct axis is zero. I just want check the direction
110                         Vector3 resultXYZ = cut.Xyz;
111
112                         Assert.True(QuaternionTestHelper.VerifyEqualSingleDirection(resultXYZ, expectedResult));
113                 }
114
115                 /// <summary>
116                 /// Checks if a single given value (either pitch, yaw or roll) get converted into correct x,y,z value of quaternion.
117                 /// </summary>
118                 /// <param name="eulerValues">euler angle values</param>
119                 /// <param name="expectedResult">expected xyz component of quaternion</param>
120                 /// <param name="testName">Taken from nUnit test data. Don't know how to name data driven tests for xUnit which actually works.</param>
121                 [Theory]
122                 [MemberData(nameof(QuaternionTestDataGenerator.SingleAxisTestCases), MemberType = typeof(QuaternionTestDataGenerator))]
123                 public void CtorEulerAnglesVector3_SingleEulerAngleSet_RotateCorrectAxis(Vector3 eulerValues, Vector3 expectedResult, String testName)
124                 {
125                         //Arrange + Act: Create Quaternion with "pitch/yaw/roll"
126                         var cut = new Quaternion(eulerValues.X, eulerValues.Y, eulerValues.Z);
127
128                         //Assert: Use helper, to check if part of the two correct axis is zero. I just want check the direction
129                         Vector3 resultXYZ = cut.Xyz;
130
131                         Assert.True(QuaternionTestHelper.VerifyEqualSingleDirection(resultXYZ, expectedResult));
132                 }
133
134                 /// <summary>
135                 /// Checks if a single given value (either pitch, yaw or roll) get converted into correct x,y,z value of quaternion.
136                 /// </summary>
137                 /// <param name="eulerValues">euler angle values</param>
138                 /// <param name="expectedResult">expected xyz component of quaternion</param>
139                 /// <param name="testName">Taken from nUnit test data. Don't know how to name data driven tests for xUnit which actually works.</param>
140                 [Theory]
141                 [MemberData(nameof(QuaternionTestDataGenerator.SingleAxisTestCases), MemberType = typeof(QuaternionTestDataGenerator))]
142                 public void FromEulerAnglesFloat_SingleEulerAngleSet_RotateCorrectAxis(Vector3 eulerValues, Vector3 expectedResult, String testName)
143                 {
144                         //Arrange + Act: Create Quaternion with "pitch/yaw/roll"
145                         var cut = Quaternion.FromEulerAngles(eulerValues.X, eulerValues.Y, eulerValues.Z);
146
147                         //Assert: Use helper, to check if part of the two correct axis is zero. I just want check the direction
148                         Vector3 resultXYZ = cut.Xyz;
149
150                         Assert.True(QuaternionTestHelper.VerifyEqualSingleDirection(resultXYZ, expectedResult));
151                 }
152
153                 /// <summary>
154                 /// Checks if a single given value (either pitch, yaw or roll) get converted into correct x,y,z value of quaternion.
155                 /// </summary>
156                 /// <param name="eulerValues">euler angle values</param>
157                 /// <param name="expectedResult">expected xyz component of quaternion</param>
158                 /// <param name="testName">Taken from nUnit test data. Don't know how to name data driven tests for xUnit which actually works.</param>
159                 [Theory]
160                 [MemberData(nameof(QuaternionTestDataGenerator.SingleAxisTestCases), MemberType = typeof(QuaternionTestDataGenerator))]
161                 public void FromEulerAnglesVector3_SingleEulerAngleSet_RotateCorrectAxis(Vector3 eulerValues, Vector3 expectedResult, String testName)
162                 {
163                         //Arrange + Act: Create Quaternion with "pitch/yaw/roll"
164                         var cut = Quaternion.FromEulerAngles(eulerValues);
165
166                         //Assert: Use helper, to check if part of the two correct axis is zero. I just want check the direction
167                         Vector3 resultXYZ = cut.Xyz;
168
169                         Assert.True(QuaternionTestHelper.VerifyEqualSingleDirection(resultXYZ, expectedResult));
170                 }
171
172                 /// <summary>
173                 /// Checks if a single given value (either pitch, yaw or roll) get converted into correct x,y,z value of quaternion.
174                 /// </summary>
175                 /// <param name="eulerValues">euler angle values</param>
176                 /// <param name="expectedResult">expected xyz component of quaternion</param>
177                 /// <param name="testName">Taken from nUnit test data. Don't know how to name data driven tests for xUnit which actually works.</param>
178                 [Theory]
179                 [MemberData(nameof(QuaternionTestDataGenerator.SingleAxisTestCases), MemberType = typeof(QuaternionTestDataGenerator))]
180                 public void FromEulerAnglesOut_SingleEulerAngleSet_RotateCorrectAxis(Vector3 eulerValues, Vector3 expectedResult, String testName)
181                 {
182                         //Arrange + Act: Create Quaternion with "pitch/yaw/roll"
183                         var cut = Quaternion.Identity;
184                         Quaternion.FromEulerAngles(ref eulerValues, out cut);
185
186                         //Assert: Use helper, to check if part of the two correct axis is zero. I just want check the direction
187                         Vector3 resultXYZ = cut.Xyz;
188
189                         Assert.True(QuaternionTestHelper.VerifyEqualSingleDirection(resultXYZ, expectedResult));
190                 }
191
192                 /// <summary>
193                 /// Check if a quaternion returns a a rotation about the correct coordinate axis
194                 /// </summary>
195                 /// <param name="cut">Prepared Quaternion</param>
196                 /// <param name="expectedResult">Expected result.</param>
197                 /// <param name="testName">Taken from nUnit test data. Don't know how to name data driven tests for xUnit which actually works.</param>
198                 [Theory]
199                 [MemberData(nameof(QuaternionTestDataGenerator.ToAxisAngleTestCases), MemberType = typeof(QuaternionTestDataGenerator))]
200                 public void ToAxisAngle_SingleAxisSetAndAngleIgnored_RotateCorrectAxis(Quaternion cut, Vector3 expectedResult, String testName)
201                 {
202                         //Arrange + Act: Create Quaternion with rotation about X/Y/Z axis
203                         Vector3 resultXYZ;
204                         float dontCare;
205                         cut.ToAxisAngle(out resultXYZ, out dontCare);
206
207                         //Assert: Use helper, to check if part of the two correct axis is zero. I just want check the direction
208                         Assert.True(QuaternionTestHelper.VerifyEqualSingleDirection(resultXYZ, expectedResult));
209                 }
210
211                 //TODO: Make also checks with rotation angle
212         }
213 }
214