diff --git a/tests/OpenTK.Tests.Math/OpenTK.Tests.Math.csproj b/tests/OpenTK.Tests.Math/OpenTK.Tests.Math.csproj
index 9b2ccec8..07882b1d 100644
--- a/tests/OpenTK.Tests.Math/OpenTK.Tests.Math.csproj
+++ b/tests/OpenTK.Tests.Math/OpenTK.Tests.Math.csproj
@@ -47,6 +47,7 @@
+
diff --git a/tests/OpenTK.Tests.Math/QuaternionTests.cs b/tests/OpenTK.Tests.Math/QuaternionTests.cs
new file mode 100644
index 00000000..27f0a28b
--- /dev/null
+++ b/tests/OpenTK.Tests.Math/QuaternionTests.cs
@@ -0,0 +1,214 @@
+using Xunit;
+using System;
+using System.Collections.Generic;
+
+namespace OpenTK.Tests.Math
+{
+ ///
+ /// Generates Quaternion test data.
+ ///
+ public class QuaternionTestDataGenerator
+ {
+ ///
+ /// Returns the single axis test cases.
+ /// 1. param: rotation in euler angles
+ /// 2. param: expected result of xyz-component of quaternion
+ /// 3. param: test name (Don't found a working way how to pass this to xUnit runner). I let it here for test documentation
+ ///
+ /// The single axis test cases.
+ public static IEnumerable SingleAxisTestCases()
+ {
+ yield return new object[] { new Vector3(1, 0, 0), Vector3.UnitX, "Rotate around x axis" };
+ yield return new object[] { new Vector3(0, 1, 0), Vector3.UnitY, "Rotate around y axis" };
+ yield return new object[] { new Vector3(0, 0, 1), Vector3.UnitZ, "Rotate around z axis" };
+ }
+
+ ///
+ /// Returns the single ToAxisAngle test cases.
+ /// 1. param: Quaternion which a definied value of xyz-component.
+ /// 2. param: expected result of xyz-component of quaternion
+ /// 3. param: test name (Don't found a working way how to pass this to xUnit runner). I let it here for test documentation
+ ///
+ /// The single axis test cases.
+ public static IEnumerable ToAxisAngleTestCases()
+ {
+ yield return new object[] { new Quaternion(Vector3.UnitX, 0), Vector3.UnitX, "Rotate around x axis" };
+ yield return new object[] { new Quaternion(Vector3.UnitY, 0), Vector3.UnitY, "Rotate around y axis" };
+ yield return new object[] { new Quaternion(Vector3.UnitZ, 0), Vector3.UnitZ, "Rotate around z axis" };
+ }
+ }
+
+ ///
+ /// Provides some methods which helps to verify test results
+ ///
+ internal static class QuaternionTestHelper
+ {
+ ///
+ /// Verifies the direction of an given .
+ ///
+ /// false: When does contain xyz values, when it should be 0,
+ /// or does not contain 0 when it should be
+ /// To test
+ /// Expected directions. Values getting only 0 checked
+ public static bool VerifyEuqalSignleDirection(Vector3 toTest, Vector3 expected)
+ {
+ //To verify the direction of an vector, just respect the 0 values and check against these.
+ //The length of the vectors are ignored.
+ if (expected.X == 0)
+ {
+ if (toTest.X != 0)
+ return false;
+ }
+ else
+ {
+ if (toTest.X == 0)
+ return false;
+ }
+
+ if (expected.Y == 0)
+ {
+ if (toTest.Y != 0)
+ return false;
+ }
+ else
+ {
+ if (toTest.Y == 0)
+ return false;
+ }
+
+ if (expected.Z == 0)
+ {
+ if (toTest.Z != 0)
+ return false;
+ }
+ else
+ {
+ if (toTest.Z == 0)
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ public class Quaternion_Tests
+ {
+ ///
+ /// Checks if a single given value (either pitch, yaw or roll) get converted into correct x,y,z value of quaternion.
+ ///
+ /// euler angle values
+ /// expected xyz component of quaternion
+ /// Taken from nUnit test data. Don't know how to name data driven tests for xUnit which actually works.
+ [Theory]
+ [MemberData(nameof(QuaternionTestDataGenerator.SingleAxisTestCases), MemberType = typeof(QuaternionTestDataGenerator))]
+ public void CtorEulerAnglesFloat_SingleEulerAngleSet_RotateCorrectAxis(Vector3 eulerValues, Vector3 expectedResult, String testName)
+ {
+ //Arrange + Act: Create Quaternion with "pitch/yaw/roll"
+ var cut = new Quaternion(eulerValues.X, eulerValues.Y, eulerValues.Z);
+
+ //Assert: Use helper, to check if part of the two correct axis is zero. I just want check the direction
+ Vector3 resultXYZ = cut.Xyz;
+
+ Assert.True(QuaternionTestHelper.VerifyEuqalSignleDirection(resultXYZ, expectedResult));
+ }
+
+ ///
+ /// Checks if a single given value (either pitch, yaw or roll) get converted into correct x,y,z value of quaternion.
+ ///
+ /// euler angle values
+ /// expected xyz component of quaternion
+ /// Taken from nUnit test data. Don't know how to name data driven tests for xUnit which actually works.
+ [Theory]
+ [MemberData(nameof(QuaternionTestDataGenerator.SingleAxisTestCases), MemberType = typeof(QuaternionTestDataGenerator))]
+ public void CtorEulerAnglesVector3_SingleEulerAngleSet_RotateCorrectAxis(Vector3 eulerValues, Vector3 expectedResult, String testName)
+ {
+ //Arrange + Act: Create Quaternion with "pitch/yaw/roll"
+ var cut = new Quaternion(eulerValues.X, eulerValues.Y, eulerValues.Z);
+
+ //Assert: Use helper, to check if part of the two correct axis is zero. I just want check the direction
+ Vector3 resultXYZ = cut.Xyz;
+
+ Assert.True(QuaternionTestHelper.VerifyEuqalSignleDirection(resultXYZ, expectedResult));
+ }
+
+ ///
+ /// Checks if a single given value (either pitch, yaw or roll) get converted into correct x,y,z value of quaternion.
+ ///
+ /// euler angle values
+ /// expected xyz component of quaternion
+ /// Taken from nUnit test data. Don't know how to name data driven tests for xUnit which actually works.
+ [Theory]
+ [MemberData(nameof(QuaternionTestDataGenerator.SingleAxisTestCases), MemberType = typeof(QuaternionTestDataGenerator))]
+ public void FromEulerAnglesFloat_SingleEulerAngleSet_RotateCorrectAxis(Vector3 eulerValues, Vector3 expectedResult, String testName)
+ {
+ //Arrange + Act: Create Quaternion with "pitch/yaw/roll"
+ var cut = Quaternion.FromEulerAngles(eulerValues.X, eulerValues.Y, eulerValues.Z);
+
+ //Assert: Use helper, to check if part of the two correct axis is zero. I just want check the direction
+ Vector3 resultXYZ = cut.Xyz;
+
+ Assert.True(QuaternionTestHelper.VerifyEuqalSignleDirection(resultXYZ, expectedResult));
+ }
+
+ ///
+ /// Checks if a single given value (either pitch, yaw or roll) get converted into correct x,y,z value of quaternion.
+ ///
+ /// euler angle values
+ /// expected xyz component of quaternion
+ /// Taken from nUnit test data. Don't know how to name data driven tests for xUnit which actually works.
+ [Theory]
+ [MemberData(nameof(QuaternionTestDataGenerator.SingleAxisTestCases), MemberType = typeof(QuaternionTestDataGenerator))]
+ public void FromEulerAnglesVector3_SingleEulerAngleSet_RotateCorrectAxis(Vector3 eulerValues, Vector3 expectedResult, String testName)
+ {
+ //Arrange + Act: Create Quaternion with "pitch/yaw/roll"
+ var cut = Quaternion.FromEulerAngles(eulerValues);
+
+ //Assert: Use helper, to check if part of the two correct axis is zero. I just want check the direction
+ Vector3 resultXYZ = cut.Xyz;
+
+ Assert.True(QuaternionTestHelper.VerifyEuqalSignleDirection(resultXYZ, expectedResult));
+ }
+
+ ///
+ /// Checks if a single given value (either pitch, yaw or roll) get converted into correct x,y,z value of quaternion.
+ ///
+ /// euler angle values
+ /// expected xyz component of quaternion
+ /// Taken from nUnit test data. Don't know how to name data driven tests for xUnit which actually works.
+ [Theory]
+ [MemberData(nameof(QuaternionTestDataGenerator.SingleAxisTestCases), MemberType = typeof(QuaternionTestDataGenerator))]
+ public void FromEulerAnglesOut_SingleEulerAngleSet_RotateCorrectAxis(Vector3 eulerValues, Vector3 expectedResult, String testName)
+ {
+ //Arrange + Act: Create Quaternion with "pitch/yaw/roll"
+ var cut = Quaternion.Identity;
+ Quaternion.FromEulerAngles(ref eulerValues, out cut);
+
+ //Assert: Use helper, to check if part of the two correct axis is zero. I just want check the direction
+ Vector3 resultXYZ = cut.Xyz;
+
+ Assert.True(QuaternionTestHelper.VerifyEuqalSignleDirection(resultXYZ, expectedResult));
+ }
+
+ ///
+ /// Check if a quaternion returns a a rotation about the correct coordinate axis
+ ///
+ /// Prepared Quaternion
+ /// Expected result.
+ /// Taken from nUnit test data. Don't know how to name data driven tests for xUnit which actually works.
+ [Theory]
+ [MemberData(nameof(QuaternionTestDataGenerator.ToAxisAngleTestCases), MemberType = typeof(QuaternionTestDataGenerator))]
+ public void ToAxisAngle_SingleAxisSetAndAngleIgnored_RotateCorrectAxis(Quaternion cut, Vector3 expectedResult, String testName)
+ {
+ //Arrange + Act: Create Quaternion with rotation about X/Y/Z axis
+ Vector3 resultXYZ;
+ float dontCare;
+ cut.ToAxisAngle(out resultXYZ, out dontCare);
+
+ //Assert: Use helper, to check if part of the two correct axis is zero. I just want check the direction
+ Assert.True(QuaternionTestHelper.VerifyEuqalSignleDirection(resultXYZ, expectedResult));
+ }
+
+ //TODO: Make also checks with rotation angle
+ }
+}
+