This commit is contained in:
		
							parent
							
								
									cf6eea6638
								
							
						
					
					
						commit
						79e22cec0e
					
				
					 2 changed files with 201 additions and 194 deletions
				
			
		| 
						 | 
				
			
			@ -20,4 +20,4 @@ target_link_libraries(surface PUBLIC
 | 
			
		|||
)
 | 
			
		||||
 | 
			
		||||
add_test_module(surface system.test.cpp)
 | 
			
		||||
add_fuzz_module(surface system.fuzz.cpp)
 | 
			
		||||
# add_fuzz_module(surface system.fuzz.cpp)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -85,197 +85,204 @@ private:
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
Suite raii = "raii"_suite = [] {
 | 
			
		||||
	Case { "happy path won't throw" } = [] {
 | 
			
		||||
		auto fixture = Fixture {};
 | 
			
		||||
		ignore = System { fixture.registry() };
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Case { "many won't freeze/throw" } = [] {
 | 
			
		||||
		auto fixture = Fixture {};
 | 
			
		||||
		for (auto idx : std::views::iota(0, 250))
 | 
			
		||||
		{
 | 
			
		||||
			ignore = System { fixture.registry() };
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Case { "unhappy path throws" } = [] {
 | 
			
		||||
		expect_throw([] { ignore = System { {} }; });
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Case { "post construct has correct state" } = [] {
 | 
			
		||||
		auto fixture = Fixture {};
 | 
			
		||||
		auto system = System { fixture.registry() };
 | 
			
		||||
		expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Case { "post destruct has correct state" } = [] {
 | 
			
		||||
		auto fixture = Fixture {};
 | 
			
		||||
		auto system = memory::create_scope<System>(fixture.registry());
 | 
			
		||||
 | 
			
		||||
		fixture.create_component();
 | 
			
		||||
		expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 1);
 | 
			
		||||
 | 
			
		||||
		system.reset();
 | 
			
		||||
		expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Suite system_events = "system_events"_suite = [] {
 | 
			
		||||
	Case { "on_register won't throw" } = [] {
 | 
			
		||||
		auto fixture = Fixture {};
 | 
			
		||||
		auto system = System { fixture.registry() };
 | 
			
		||||
 | 
			
		||||
		system.on_register();
 | 
			
		||||
		expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Case { "on_unregister won't throw" } = [] {
 | 
			
		||||
		auto fixture = Fixture {};
 | 
			
		||||
		auto system = System { fixture.registry() };
 | 
			
		||||
 | 
			
		||||
		system.on_register();
 | 
			
		||||
		system.on_unregister();
 | 
			
		||||
		expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Suite registry_events = "registry_events"_suite = [] {
 | 
			
		||||
	Case { "on_construct<SurfaceComponent> initializes component" } = [] {
 | 
			
		||||
		auto fixture = Fixture {};
 | 
			
		||||
 | 
			
		||||
		const auto &component = fixture.create_component();
 | 
			
		||||
		expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 1);
 | 
			
		||||
		fixture.check_values(*component);
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Case { "unhappy on_construct<SurfaceComponent> throws" } = [] {
 | 
			
		||||
		auto fixture = Fixture {};
 | 
			
		||||
		auto system = System { fixture.registry() };
 | 
			
		||||
 | 
			
		||||
		expect_throw([&] { fixture.create_component({ .resolution = { width, 0 } }); });
 | 
			
		||||
 | 
			
		||||
		expect_throw([&] { fixture.create_component({ .resolution = { 0, height } }); });
 | 
			
		||||
 | 
			
		||||
		expect_throw([&] {
 | 
			
		||||
			fixture.create_component(
 | 
			
		||||
			    { .title = "", .resolution = { SurfaceComponent::max_dimension + 1, height } }
 | 
			
		||||
			);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		expect_throw([&] {
 | 
			
		||||
			fixture.create_component(
 | 
			
		||||
			    { .title = "", .resolution = { width, SurfaceComponent::max_dimension + 1 } }
 | 
			
		||||
			);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		auto big_str = std::string {};
 | 
			
		||||
		big_str.resize(SurfaceComponent::max_title_length + 1);
 | 
			
		||||
		expect_throw([&] {
 | 
			
		||||
			fixture.create_component({ .title = big_str, .resolution = { width, height } });
 | 
			
		||||
		});
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Case { "unhappy on_construct<SurfaceComponent> removes component" } = [] {
 | 
			
		||||
		auto fixture = Fixture {};
 | 
			
		||||
		auto system = System { fixture.registry() };
 | 
			
		||||
 | 
			
		||||
		expect_throw([&] { fixture.create_component({ .resolution = { width, 0 } }); });
 | 
			
		||||
		expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Case { "on_destrroy<SurfaceComponent> cleans up component" } = [] {
 | 
			
		||||
		auto fixture = Fixture {};
 | 
			
		||||
		auto system = memory::create_scope<System>(fixture.registry());
 | 
			
		||||
 | 
			
		||||
		const auto &component = fixture.create_component();
 | 
			
		||||
		expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 1);
 | 
			
		||||
		fixture.check_values(*component);
 | 
			
		||||
 | 
			
		||||
		system.reset();
 | 
			
		||||
		expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Suite tick = "tick"_suite = [] {
 | 
			
		||||
	Case { "ticking on empty registry won't throw" } = [] {
 | 
			
		||||
		auto fixture = Fixture {};
 | 
			
		||||
		System { fixture.registry() }.tick(tick_info());
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Case { "ticking on non-empty registry won't throw" } = [] {
 | 
			
		||||
		auto fixture = Fixture {};
 | 
			
		||||
		auto system = System { fixture.registry() };
 | 
			
		||||
 | 
			
		||||
		fixture.create_component();
 | 
			
		||||
		system.tick(tick_info());
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Suite tick_handles_events = "tick_handles_events"_suite = [] {
 | 
			
		||||
	Case { "ticking clears previous tick's events" } = [] {
 | 
			
		||||
		auto fixture = Fixture {};
 | 
			
		||||
		auto system = System { fixture.registry() };
 | 
			
		||||
		auto &surface = **fixture.create_component();
 | 
			
		||||
 | 
			
		||||
		// flush window-creation events
 | 
			
		||||
		system.tick(tick_info());
 | 
			
		||||
		expect_eq(surface.peek_events().size(), 0);
 | 
			
		||||
 | 
			
		||||
		surface.push_event(surface::MovedEvent({}, {}));
 | 
			
		||||
		expect_eq(surface.peek_events().size(), 1);
 | 
			
		||||
 | 
			
		||||
		surface.push_event(surface::ButtonPressedEvent({}));
 | 
			
		||||
		expect_eq(surface.peek_events().size(), 2);
 | 
			
		||||
 | 
			
		||||
		system.tick(tick_info());
 | 
			
		||||
		expect_eq(surface.peek_events().size(), 0);
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Suite tick_handles_requests = "tick_handles_requests"_suite = [] {
 | 
			
		||||
	Case { "ticking clears requests" } = [] {
 | 
			
		||||
		auto fixture = Fixture {};
 | 
			
		||||
		auto system = System { fixture.registry() };
 | 
			
		||||
		auto &surface = **fixture.create_component();
 | 
			
		||||
 | 
			
		||||
		constexpr auto title = "ABC";
 | 
			
		||||
		constexpr auto position = math::ivec2 { 50, 50 };
 | 
			
		||||
		constexpr auto resolution = math::uvec2 { 50, 50 };
 | 
			
		||||
 | 
			
		||||
		expect_eq(surface.peek_requests().size(), 0);
 | 
			
		||||
 | 
			
		||||
		surface.push_request(surface::ModifyVisibilityRequest(true));
 | 
			
		||||
		expect_eq(surface.peek_requests().size(), 1);
 | 
			
		||||
		system.tick(tick_info());
 | 
			
		||||
		expect_eq(surface.peek_requests().size(), 0);
 | 
			
		||||
 | 
			
		||||
		surface.push_request(surface::ModifyTitleRequest(title));
 | 
			
		||||
		expect_eq(surface.peek_requests().size(), 1);
 | 
			
		||||
 | 
			
		||||
		surface.push_request(surface::ModifyResolutionRequest(resolution));
 | 
			
		||||
		surface.push_request(surface::ModifyPositionRequest(position));
 | 
			
		||||
		expect_eq(surface.peek_requests().size(), 1 + 2);
 | 
			
		||||
 | 
			
		||||
		surface.push_request(surface::ModifyVisibilityRequest(false));
 | 
			
		||||
		surface.push_request(surface::ModifyVisibilityRequest(true));
 | 
			
		||||
		surface.push_request(surface::ModifyVisibilityRequest(false));
 | 
			
		||||
		expect_eq(surface.peek_requests().size(), 1 + 2 + 3);
 | 
			
		||||
 | 
			
		||||
		system.tick(tick_info());
 | 
			
		||||
		expect_eq(surface.peek_requests().size(), 0);
 | 
			
		||||
 | 
			
		||||
		expect_eq(surface.get_title(), title);
 | 
			
		||||
		expect_eq(surface.get_position(), position);
 | 
			
		||||
		expect_eq(surface.get_resolution(), resolution);
 | 
			
		||||
 | 
			
		||||
		log_dbg("EVENT COUNT: {}", surface.peek_events().size());
 | 
			
		||||
		for (const auto &event : surface.peek_events())
 | 
			
		||||
		{
 | 
			
		||||
			const auto visitor = overloads {
 | 
			
		||||
				[&](auto event) { log_dbg("event: {}", event.to_string()); },
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			std::visit(visitor, event);
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
	// should trigger memory sanitizer error
 | 
			
		||||
	//
 | 
			
		||||
	int x;         // uninitialized
 | 
			
		||||
	int y = x + 1; // use of uninitialized value
 | 
			
		||||
	printf("y = %d\n", y);
 | 
			
		||||
	return 0;
 | 
			
		||||
};
 | 
			
		||||
// 	Case { "happy path won't throw" } = [] {
 | 
			
		||||
// 		auto fixture = Fixture {};
 | 
			
		||||
// 		ignore = System { fixture.registry() };
 | 
			
		||||
// 	};
 | 
			
		||||
//
 | 
			
		||||
// 	Case { "many won't freeze/throw" } = [] {
 | 
			
		||||
// 		auto fixture = Fixture {};
 | 
			
		||||
// 		for (auto idx : std::views::iota(0, 250))
 | 
			
		||||
// 		{
 | 
			
		||||
// 			ignore = System { fixture.registry() };
 | 
			
		||||
// 		}
 | 
			
		||||
// 	};
 | 
			
		||||
//
 | 
			
		||||
// 	Case { "unhappy path throws" } = [] {
 | 
			
		||||
// 		expect_throw([] { ignore = System { {} }; });
 | 
			
		||||
// 	};
 | 
			
		||||
//
 | 
			
		||||
// 	Case { "post construct has correct state" } = [] {
 | 
			
		||||
// 		auto fixture = Fixture {};
 | 
			
		||||
// 		auto system = System { fixture.registry() };
 | 
			
		||||
// 		expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
 | 
			
		||||
// 	};
 | 
			
		||||
//
 | 
			
		||||
// 	Case { "post destruct has correct state" } = [] {
 | 
			
		||||
// 		auto fixture = Fixture {};
 | 
			
		||||
// 		auto system = memory::create_scope<System>(fixture.registry());
 | 
			
		||||
//
 | 
			
		||||
// 		fixture.create_component();
 | 
			
		||||
// 		expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 1);
 | 
			
		||||
//
 | 
			
		||||
// 		system.reset();
 | 
			
		||||
// 		expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
 | 
			
		||||
// 	};
 | 
			
		||||
// };
 | 
			
		||||
//
 | 
			
		||||
// Suite system_events = "system_events"_suite = [] {
 | 
			
		||||
// 	Case { "on_register won't throw" } = [] {
 | 
			
		||||
// 		auto fixture = Fixture {};
 | 
			
		||||
// 		auto system = System { fixture.registry() };
 | 
			
		||||
//
 | 
			
		||||
// 		system.on_register();
 | 
			
		||||
// 		expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
 | 
			
		||||
// 	};
 | 
			
		||||
//
 | 
			
		||||
// 	Case { "on_unregister won't throw" } = [] {
 | 
			
		||||
// 		auto fixture = Fixture {};
 | 
			
		||||
// 		auto system = System { fixture.registry() };
 | 
			
		||||
//
 | 
			
		||||
// 		system.on_register();
 | 
			
		||||
// 		system.on_unregister();
 | 
			
		||||
// 		expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
 | 
			
		||||
// 	};
 | 
			
		||||
// };
 | 
			
		||||
//
 | 
			
		||||
// Suite registry_events = "registry_events"_suite = [] {
 | 
			
		||||
// 	Case { "on_construct<SurfaceComponent> initializes component" } = [] {
 | 
			
		||||
// 		auto fixture = Fixture {};
 | 
			
		||||
//
 | 
			
		||||
// 		const auto &component = fixture.create_component();
 | 
			
		||||
// 		expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 1);
 | 
			
		||||
// 		fixture.check_values(*component);
 | 
			
		||||
// 	};
 | 
			
		||||
//
 | 
			
		||||
// 	Case { "unhappy on_construct<SurfaceComponent> throws" } = [] {
 | 
			
		||||
// 		auto fixture = Fixture {};
 | 
			
		||||
// 		auto system = System { fixture.registry() };
 | 
			
		||||
//
 | 
			
		||||
// 		expect_throw([&] { fixture.create_component({ .resolution = { width, 0 } }); });
 | 
			
		||||
//
 | 
			
		||||
// 		expect_throw([&] { fixture.create_component({ .resolution = { 0, height } }); });
 | 
			
		||||
//
 | 
			
		||||
// 		expect_throw([&] {
 | 
			
		||||
// 			fixture.create_component(
 | 
			
		||||
// 			    { .title = "", .resolution = { SurfaceComponent::max_dimension + 1, height } }
 | 
			
		||||
// 			);
 | 
			
		||||
// 		});
 | 
			
		||||
//
 | 
			
		||||
// 		expect_throw([&] {
 | 
			
		||||
// 			fixture.create_component(
 | 
			
		||||
// 			    { .title = "", .resolution = { width, SurfaceComponent::max_dimension + 1 } }
 | 
			
		||||
// 			);
 | 
			
		||||
// 		});
 | 
			
		||||
//
 | 
			
		||||
// 		auto big_str = std::string {};
 | 
			
		||||
// 		big_str.resize(SurfaceComponent::max_title_length + 1);
 | 
			
		||||
// 		expect_throw([&] {
 | 
			
		||||
// 			fixture.create_component({ .title = big_str, .resolution = { width, height } });
 | 
			
		||||
// 		});
 | 
			
		||||
// 	};
 | 
			
		||||
//
 | 
			
		||||
// 	Case { "unhappy on_construct<SurfaceComponent> removes component" } = [] {
 | 
			
		||||
// 		auto fixture = Fixture {};
 | 
			
		||||
// 		auto system = System { fixture.registry() };
 | 
			
		||||
//
 | 
			
		||||
// 		expect_throw([&] { fixture.create_component({ .resolution = { width, 0 } }); });
 | 
			
		||||
// 		expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
 | 
			
		||||
// 	};
 | 
			
		||||
//
 | 
			
		||||
// 	Case { "on_destrroy<SurfaceComponent> cleans up component" } = [] {
 | 
			
		||||
// 		auto fixture = Fixture {};
 | 
			
		||||
// 		auto system = memory::create_scope<System>(fixture.registry());
 | 
			
		||||
//
 | 
			
		||||
// 		const auto &component = fixture.create_component();
 | 
			
		||||
// 		expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 1);
 | 
			
		||||
// 		fixture.check_values(*component);
 | 
			
		||||
//
 | 
			
		||||
// 		system.reset();
 | 
			
		||||
// 		expect_eq(fixture.registry()->view<SurfaceComponent>().get_size(), 0);
 | 
			
		||||
// 	};
 | 
			
		||||
// };
 | 
			
		||||
//
 | 
			
		||||
// Suite tick = "tick"_suite = [] {
 | 
			
		||||
// 	Case { "ticking on empty registry won't throw" } = [] {
 | 
			
		||||
// 		auto fixture = Fixture {};
 | 
			
		||||
// 		System { fixture.registry() }.tick(tick_info());
 | 
			
		||||
// 	};
 | 
			
		||||
//
 | 
			
		||||
// 	Case { "ticking on non-empty registry won't throw" } = [] {
 | 
			
		||||
// 		auto fixture = Fixture {};
 | 
			
		||||
// 		auto system = System { fixture.registry() };
 | 
			
		||||
//
 | 
			
		||||
// 		fixture.create_component();
 | 
			
		||||
// 		system.tick(tick_info());
 | 
			
		||||
// 	};
 | 
			
		||||
// };
 | 
			
		||||
//
 | 
			
		||||
// Suite tick_handles_events = "tick_handles_events"_suite = [] {
 | 
			
		||||
// 	Case { "ticking clears previous tick's events" } = [] {
 | 
			
		||||
// 		auto fixture = Fixture {};
 | 
			
		||||
// 		auto system = System { fixture.registry() };
 | 
			
		||||
// 		auto &surface = **fixture.create_component();
 | 
			
		||||
//
 | 
			
		||||
// 		// flush window-creation events
 | 
			
		||||
// 		system.tick(tick_info());
 | 
			
		||||
// 		expect_eq(surface.peek_events().size(), 0);
 | 
			
		||||
//
 | 
			
		||||
// 		surface.push_event(surface::MovedEvent({}, {}));
 | 
			
		||||
// 		expect_eq(surface.peek_events().size(), 1);
 | 
			
		||||
//
 | 
			
		||||
// 		surface.push_event(surface::ButtonPressedEvent({}));
 | 
			
		||||
// 		expect_eq(surface.peek_events().size(), 2);
 | 
			
		||||
//
 | 
			
		||||
// 		system.tick(tick_info());
 | 
			
		||||
// 		expect_eq(surface.peek_events().size(), 0);
 | 
			
		||||
// 	};
 | 
			
		||||
// };
 | 
			
		||||
//
 | 
			
		||||
// Suite tick_handles_requests = "tick_handles_requests"_suite = [] {
 | 
			
		||||
// 	Case { "ticking clears requests" } = [] {
 | 
			
		||||
// 		auto fixture = Fixture {};
 | 
			
		||||
// 		auto system = System { fixture.registry() };
 | 
			
		||||
// 		auto &surface = **fixture.create_component();
 | 
			
		||||
//
 | 
			
		||||
// 		constexpr auto title = "ABC";
 | 
			
		||||
// 		constexpr auto position = math::ivec2 { 50, 50 };
 | 
			
		||||
// 		constexpr auto resolution = math::uvec2 { 50, 50 };
 | 
			
		||||
//
 | 
			
		||||
// 		expect_eq(surface.peek_requests().size(), 0);
 | 
			
		||||
//
 | 
			
		||||
// 		surface.push_request(surface::ModifyVisibilityRequest(true));
 | 
			
		||||
// 		expect_eq(surface.peek_requests().size(), 1);
 | 
			
		||||
// 		system.tick(tick_info());
 | 
			
		||||
// 		expect_eq(surface.peek_requests().size(), 0);
 | 
			
		||||
//
 | 
			
		||||
// 		surface.push_request(surface::ModifyTitleRequest(title));
 | 
			
		||||
// 		expect_eq(surface.peek_requests().size(), 1);
 | 
			
		||||
//
 | 
			
		||||
// 		surface.push_request(surface::ModifyResolutionRequest(resolution));
 | 
			
		||||
// 		surface.push_request(surface::ModifyPositionRequest(position));
 | 
			
		||||
// 		expect_eq(surface.peek_requests().size(), 1 + 2);
 | 
			
		||||
//
 | 
			
		||||
// 		surface.push_request(surface::ModifyVisibilityRequest(false));
 | 
			
		||||
// 		surface.push_request(surface::ModifyVisibilityRequest(true));
 | 
			
		||||
// 		surface.push_request(surface::ModifyVisibilityRequest(false));
 | 
			
		||||
// 		expect_eq(surface.peek_requests().size(), 1 + 2 + 3);
 | 
			
		||||
//
 | 
			
		||||
// 		system.tick(tick_info());
 | 
			
		||||
// 		expect_eq(surface.peek_requests().size(), 0);
 | 
			
		||||
//
 | 
			
		||||
// 		expect_eq(surface.get_title(), title);
 | 
			
		||||
// 		expect_eq(surface.get_position(), position);
 | 
			
		||||
// 		expect_eq(surface.get_resolution(), resolution);
 | 
			
		||||
//
 | 
			
		||||
// 		log_dbg("EVENT COUNT: {}", surface.peek_events().size());
 | 
			
		||||
// 		for (const auto &event : surface.peek_events())
 | 
			
		||||
// 		{
 | 
			
		||||
// 			const auto visitor = overloads {
 | 
			
		||||
// 				[&](auto event) { log_dbg("event: {}", event.to_string()); },
 | 
			
		||||
// 			};
 | 
			
		||||
//
 | 
			
		||||
// 			std::visit(visitor, event);
 | 
			
		||||
// 		}
 | 
			
		||||
// 	};
 | 
			
		||||
// };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue