@@ -388,3 +388,63 @@ widget = "1.0.0"
388388}
389389
390390} // namespace
391+
392+ // ── [template.inject] self = false ───────────────────────────────────────────
393+ //
394+ // ⚠️ A TEMPLATE THAT MUST NOT DEPEND ON ITS OWN PACKAGE IS NOT HYPOTHETICAL.
395+ //
396+ // The self-dependency keeps a template from drifting from the library that
397+ // ships it, and for almost every template that is right. It is wrong for one
398+ // whose subject is depending on NOTHING: a bare-metal package may ship a kernel
399+ // starting point for a target with no C library, while the package's own module
400+ // includes <stdio.h>. Measured: the injected dependency failed to compile
401+ // before the generated project was reached, in a project whose manifest
402+ // declares no dependencies at all.
403+ TEST (ScaffoldTemplate, InjectSelfCanBeDeclined) {
404+ auto dir = std::filesystem::temp_directory_path () / " mcpp_tmpl_noself" ;
405+ std::filesystem::remove_all (dir);
406+ std::filesystem::create_directories (dir);
407+ {
408+ std::ofstream f (dir / " template.toml" );
409+ f << " [template]\n description = \" d\"\n [template.inject]\n self = false\n " ;
410+ }
411+ auto meta = mcpp::scaffold::load_meta (dir);
412+ ASSERT_TRUE (meta.has_value ()) << (meta ? " " : meta.error ());
413+ EXPECT_FALSE (meta->injectSelf );
414+ std::filesystem::remove_all (dir);
415+ }
416+
417+ // The default must stay ON: every template that does not say otherwise relies
418+ // on the injection, and a silent flip would leave them all without their own
419+ // package.
420+ TEST (ScaffoldTemplate, InjectSelfDefaultsToOn) {
421+ auto dir = std::filesystem::temp_directory_path () / " mcpp_tmpl_self_default" ;
422+ std::filesystem::remove_all (dir);
423+ std::filesystem::create_directories (dir);
424+ {
425+ std::ofstream f (dir / " template.toml" );
426+ f << " [template]\n description = \" d\"\n " ;
427+ }
428+ auto meta = mcpp::scaffold::load_meta (dir);
429+ ASSERT_TRUE (meta.has_value ()) << (meta ? " " : meta.error ());
430+ EXPECT_TRUE (meta->injectSelf );
431+ std::filesystem::remove_all (dir);
432+ }
433+
434+ // The table form still carries features, and must not be read as "declined".
435+ TEST (ScaffoldTemplate, InjectSelfTableFormStillInjects) {
436+ auto dir = std::filesystem::temp_directory_path () / " mcpp_tmpl_self_table" ;
437+ std::filesystem::remove_all (dir);
438+ std::filesystem::create_directories (dir);
439+ {
440+ std::ofstream f (dir / " template.toml" );
441+ f << " [template]\n description = \" d\"\n "
442+ " [template.inject]\n self = { features = [\" x\" ] }\n " ;
443+ }
444+ auto meta = mcpp::scaffold::load_meta (dir);
445+ ASSERT_TRUE (meta.has_value ()) << (meta ? " " : meta.error ());
446+ EXPECT_TRUE (meta->injectSelf );
447+ ASSERT_EQ (meta->injectSelfFeatures .size (), 1u );
448+ EXPECT_EQ (meta->injectSelfFeatures [0 ], " x" );
449+ std::filesystem::remove_all (dir);
450+ }
0 commit comments