Browse Source

Showing a summary of which test passed.

David Piuva 1 year ago
parent
commit
2cee2b74d7

+ 36 - 0
Source/SDK/integrationTest/Test.cpp

@@ -0,0 +1,36 @@
+
+#include "Test.h"
+
+using namespace dsr;
+
+String& string_toStreamIndented(String& target, const Grade& grade, const ReadableString& indentation) {
+	if (grade == Grade::Waiting) {
+		string_append(target, indentation, U"Waiting");
+	} else if (grade == Grade::Passed) {
+		string_append(target, indentation, U"Passed");
+	} else if (grade == Grade::Skipped) {
+		string_append(target, indentation, U"Skipped");
+	} else if (grade == Grade::Failed) {
+		string_append(target, indentation, U"Failed");
+	} else {
+		string_append(target, indentation, U"?");
+	}
+	return target;
+}
+
+// Call when completing a task but not a whole test.
+void TestContext::passTask() {
+	taskIndex++;
+}
+
+void TestContext::finishTest(Grade result) {
+	if (result == Grade::Passed) {
+		printText(U"Passed \"", tests[testIndex].name, U"\".");
+	} else if (result == Grade::Skipped) {
+		sendWarning(U"Skipped \"", tests[testIndex].name, U"\".");
+	} else if (result == Grade::Failed) {
+		sendWarning(U"Failed \"", tests[testIndex].name, U"\".");
+	}
+	tests[testIndex].result = result;
+	testIndex++;
+}

+ 5 - 15
Source/SDK/integrationTest/Test.h

@@ -14,6 +14,8 @@ enum class Grade {
 	Failed
 };
 
+dsr::String& string_toStreamIndented(dsr::String& target, const Grade& grade, const dsr::ReadableString& indentation);
+
 struct Test {
 	dsr::String name;
 	DrawContextCallback drawEvent;
@@ -22,7 +24,7 @@ struct Test {
 	bool activeDrawing;
 	Grade result = Grade::Waiting;
 	Test(const dsr::ReadableString& name, const DrawContextCallback &drawEvent, const MouseContextCallback &mouseCallback, const KeyboardContextCallback &keyboardCallback, bool activeDrawing)
-	: drawEvent(drawEvent), mouseCallback(mouseCallback), keyboardCallback(keyboardCallback), activeDrawing(activeDrawing) {}
+	: name(name), drawEvent(drawEvent), mouseCallback(mouseCallback), keyboardCallback(keyboardCallback), activeDrawing(activeDrawing) {}
 };
 
 struct TestContext {
@@ -33,22 +35,10 @@ struct TestContext {
 	int taskIndex = 0; // To avoid cluttering the summary with lots of small tests, tests are divided into smaller tasks.
 
 	// Call when completing a task but not a whole test.
-	void passTask() {
-		taskIndex++;
-	}
+	void passTask();
 
 	// Call when completing a test.
-	void finishTest(Grade result) {
-		if (result == Grade::Passed) {
-			printText(U"Passed \"", tests[testIndex].name, U"\".");
-		} else if (result == Grade::Skipped) {
-			printText(U"Skipped \"", tests[testIndex].name, U"\".");
-		} else if (result == Grade::Failed) {
-			printText(U"Failed \"", tests[testIndex].name, U"\".");
-		}
-		tests[testIndex].result = result;
-		testIndex++;
-	}
+	void finishTest(Grade result);
 
 	bool leftMouseDown = false;
 	bool middleMouseDown = false;

+ 8 - 10
Source/SDK/integrationTest/main.cpp

@@ -34,14 +34,8 @@ void dsrMain(List<String> args) {
 	window = window_create(U"Integration test", 800, 600);
 
 	// Create tests.
-	// TODO: Allow selecting which tests to add using settings and white which categories were skipped in the final summary.
-	//       Can have a screen where one gets to check types of tests and available device features.
-	//       Some might want to skip tests that require certain types of input.
-	//       One should have a mouse with vertical scroll wheel and three buttons to test it all. (The scroll wheel can often be clicked on as a middle mouse button)
-	//       The media layer currently does not support horizontal scrolling, because otherwise one would need a laptop with each operating system just to test it.
-	//       It is however cheap and easy to attach a three button mouse.
-	//       A stylus pen with only two buttons, no scroll and no relative input will only be able to perform some of the tests.
-	inputTests_populate(context.tests);
+	// TODO: Ask the user which kinds of inputs are available and use that information to select the correct tests.
+	inputTests_populate(context.tests, 3, true, true);
 
 	// Create finishing screen showing results.
 	context.tests.pushConstruct(
@@ -49,8 +43,12 @@ void dsrMain(List<String> args) {
 	,
 		[](AlignedImageRgbaU8 &canvas, TestContext &context) {
 			image_fill(canvas, ColorRgbaI32(255, 255, 255, 255));
-			font_printLine(canvas, font_getDefault(), U"Completed integration test.", IVector2D(40, 40), ColorRgbaI32(0, 0, 0, 255));
-			// TODO: Print a summary with named tests and their grades in a colored table.
+			font_printLine(canvas, font_getDefault(), U"Test summary:", IVector2D(40, 40), ColorRgbaI32(0, 0, 0, 255));
+			for (int t = 0; t < context.tests.length() - 1; t++) {
+				font_printLine(canvas, font_getDefault(), string_combine(context.tests[t].result, U" - ", context.tests[t].name), IVector2D(60, t * 20 + 60), ColorRgbaI32(0, 0, 0, 255));
+			}
+			// TODO: Allow scrolling through the results if it gets too much to fit inside the window.
+			// TODO: Also print this information to the terminal, in case that it is difficult to see.
 		}
 	,
 		[](const MouseEvent& event, TestContext &context) {}

+ 42 - 37
Source/SDK/integrationTest/tests/inputTest.cpp

@@ -3,45 +3,50 @@
 
 using namespace dsr;
 
-void inputTests_populate(List<Test> &target) {
-	target.pushConstruct(
-		U"Mouse drag test"
-	,
-		[](AlignedImageRgbaU8 &canvas, TestContext &context) {
-			image_fill(canvas, ColorRgbaI32(255, 255, 255, 255));
-			if (context.taskIndex == 0) {
-				font_printLine(canvas, font_getDefault(), U"Hover the cursor over the window.", IVector2D(40, 40), ColorRgbaI32(0, 0, 0, 255));
-			} else if (context.taskIndex == 1) {
-				font_printLine(canvas, font_getDefault(), U"Press down the left mouse key.", IVector2D(40, 40), ColorRgbaI32(0, 0, 0, 255));
-			} else if (context.taskIndex == 2) {
-				font_printLine(canvas, font_getDefault(), U"Drag the mouse over the window with the left key pressed down.", IVector2D(40, 40), ColorRgbaI32(0, 0, 0, 255));
-			} else if (context.taskIndex == 3) {
-				font_printLine(canvas, font_getDefault(), U"Release the left key.", IVector2D(40, 40), ColorRgbaI32(0, 0, 0, 255));
+void inputTests_populate(List<Test> &target, int buttonCount, bool relative, bool verticalScroll) {
+	// TODO: Make notes about which tests were skipped and why.
+	if (buttonCount >= 1) {
+		target.pushConstruct(
+			U"Mouse drag test"
+		,
+			[](AlignedImageRgbaU8 &canvas, TestContext &context) {
+				image_fill(canvas, ColorRgbaI32(255, 255, 255, 255));
+				if (context.taskIndex == 0) {
+					font_printLine(canvas, font_getDefault(), U"Hover the cursor over the window.", IVector2D(40, 40), ColorRgbaI32(0, 0, 0, 255));
+				} else if (context.taskIndex == 1) {
+					font_printLine(canvas, font_getDefault(), U"Press down the left mouse key.", IVector2D(40, 40), ColorRgbaI32(0, 0, 0, 255));
+				} else if (context.taskIndex == 2) {
+					font_printLine(canvas, font_getDefault(), U"Drag the mouse over the window with the left key pressed down.", IVector2D(40, 40), ColorRgbaI32(0, 0, 0, 255));
+				} else if (context.taskIndex == 3) {
+					font_printLine(canvas, font_getDefault(), U"Release the left key.", IVector2D(40, 40), ColorRgbaI32(0, 0, 0, 255));
+				}
 			}
-		}
-	,
-		[](const MouseEvent& event, TestContext &context) {
-			if (context.taskIndex == 0 && event.mouseEventType == MouseEventType::MouseMove && !context.leftMouseDown && !context.middleMouseDown && !context.rightMouseDown) {
-				context.passTask();
-			} else if (context.taskIndex == 1 && event.mouseEventType == MouseEventType::MouseDown) {
-				if (event.key == MouseKeyEnum::Left) {
+		,
+			[](const MouseEvent& event, TestContext &context) {
+				if (context.taskIndex == 0 && event.mouseEventType == MouseEventType::MouseMove && !context.leftMouseDown && !context.middleMouseDown && !context.rightMouseDown) {
 					context.passTask();
-				} else {
-					// TODO: Say which key was triggered instead and suggest skipping with escape if it can not be found.
-				}
-			} else if (context.taskIndex == 2 && event.mouseEventType == MouseEventType::MouseMove && context.leftMouseDown) {
-				context.passTask();
-			} else if (context.taskIndex == 3 && event.mouseEventType == MouseEventType::MouseUp) {
-				if (event.key == MouseKeyEnum::Left) {
-					context.finishTest(Grade::Passed);
-				} else {
-					// TODO: Say which key was triggered instead and suggest skipping with escape if it can not be found.
+				} else if (context.taskIndex == 1 && event.mouseEventType == MouseEventType::MouseDown) {
+					if (event.key == MouseKeyEnum::Left) {
+						context.passTask();
+					} else {
+						// TODO: Say which key was triggered instead and suggest skipping with escape if it can not be found.
+					}
+				} else if (context.taskIndex == 2 && event.mouseEventType == MouseEventType::MouseMove && context.leftMouseDown) {
+					context.passTask();
+				} else if (context.taskIndex == 3 && event.mouseEventType == MouseEventType::MouseUp) {
+					if (event.key == MouseKeyEnum::Left) {
+						context.finishTest(Grade::Passed);
+					} else {
+						// TODO: Say which key was triggered instead and suggest skipping with escape if it can not be found.
+					}
 				}
 			}
-		}
-	,
-		[](const KeyboardEvent& event, TestContext &context) {}
-	,
-		false
-	);
+		,
+			[](const KeyboardEvent& event, TestContext &context) {}
+		,
+			false
+		);
+	} else {
+		sendWarning(U"Skipped the left mouse button test, because 0 mouse buttons were selected as available.");
+	}
 }

+ 16 - 1
Source/SDK/integrationTest/tests/inputTest.h

@@ -4,6 +4,21 @@
 
 #include "../Test.h"
 
-void inputTests_populate(dsr::List<Test> &target);
+// buttonCount = 0 means that this test can not be performed at all.
+// buttonCount = 1 means that the test will only require access to the left mouse button. (physically the right button if swapped for left handed users)
+// buttonCount = 2 means that both left and right buttons are available, but not the middle button or clickable scroll wheel.
+// buttonCount = 3 means that all three mouse buttons (left, right and middle) are available.
+// While three buttons are available in the media layer, one should try to design applications to be useful even if only the left mouse button exists.
+// The right button and scroll wheel can add convenience when available to the user.
+// While more than three mouse buttons is not supported directly, they can still be bound as an extension to the keyboard using external settings.
+
+// relative = true means that the used input device applies an offset to the cursor, and then the cursor's location can be reassigned to a new location without conflicts. (mouse, stick, ball, trackpad)
+// relative = false means that the used input device sets an absolute cursor position from direct interaction with the screen, so that nothing else can move the cursor at the same time. (stylus pen, touch screen, eye-tracker)
+// Touch screens are assumed to allow light touch for hovering and hard touch for clicking, because this is essential for using desktop applications. Otherwise hover effects will be stuck on the last clicked location.
+
+// verticalScroll = true means that there exists a vertical scroll wheel or the two finger gesture to allow scrolling vertically. 
+// verticalScroll = false is used to skip all tests that require vertical scrolling.
+// Horizontal scrolling is currently not supported, because it mostly requires getting a laptop and the tests should be possible to complete with a three button mouse that can easily be moved around between computers.
+void inputTests_populate(dsr::List<Test> &target, int buttonCount = 3, bool relative = true, bool verticalScroll = true);
 
 #endif