66from metaobjects import MetaDataLoader
77from metaobjects .meta .meta_data import MetaData
88from metaobjects .codegen .config import GenConfig
9+ from metaobjects .codegen .constants import GENERATED_MARKER
910from metaobjects .codegen .runner import run_gen
1011from metaobjects .codegen .generators .entity_model import entity_model
1112
@@ -26,7 +27,51 @@ def test_run_gen_writes_a_model_per_entity(tmp_path: Path) -> None:
2627 result = run_gen (GenConfig (out_dir = str (out )), root , generators = [entity_model ()])
2728 assert (out / "Subscriber.py" ).exists ()
2829 assert "class Subscriber(BaseModel):" in (out / "Subscriber.py" ).read_text ()
29- assert [w [1 ] for w in result .files ] == ["new" ]
30+ statuses = {Path (p ).name : s for p , s in result .files }
31+ assert statuses ["Subscriber.py" ] == "new"
32+ assert statuses ["__init__.py" ] == "new" # package marker emitted alongside
33+
34+
35+ def test_run_gen_emits_importable_package_init (tmp_path : Path ) -> None :
36+ """The codegen out dir is a self-contained package: run_gen emits an
37+ ``@generated`` ``__init__.py`` so a consumer can import the generated modules
38+ (which use package-relative imports) without hand-adding a marker file that
39+ ``verify --codegen`` would then flag as ``extra``."""
40+ root = _load (tmp_path / "meta" , {"metadata.root" : {"package" : "acme" , "children" : [
41+ {"object.entity" : {"name" : "Subscriber" , "children" : [
42+ {"field.string" : {"name" : "email" , "@required" : True }},
43+ ]}},
44+ ]}})
45+ out = tmp_path / "out"
46+ run_gen (GenConfig (out_dir = str (out )), root , generators = [entity_model ()])
47+ init = out / "__init__.py"
48+ assert init .exists (), "expected a generated __init__.py in the out dir"
49+ assert GENERATED_MARKER in init .read_text (), "__init__.py must carry the @generated marker"
50+
51+
52+ def test_run_gen_package_init_can_be_disabled (tmp_path : Path ) -> None :
53+ """``emit_package_init=False`` suppresses the package marker (consumer owns it)."""
54+ root = _load (tmp_path / "meta" , {"metadata.root" : {"package" : "acme" , "children" : [
55+ {"object.entity" : {"name" : "Subscriber" , "children" : [{"field.string" : {"name" : "x" }}]}},
56+ ]}})
57+ out = tmp_path / "out"
58+ run_gen (GenConfig (out_dir = str (out ), emit_package_init = False ), root ,
59+ generators = [entity_model ()])
60+ assert not (out / "__init__.py" ).exists ()
61+
62+
63+ def test_run_gen_does_not_clobber_handwritten_package_init (tmp_path : Path ) -> None :
64+ """A hand-authored ``__init__.py`` (no @generated marker) is left untouched."""
65+ root = _load (tmp_path / "meta" , {"metadata.root" : {"package" : "acme" , "children" : [
66+ {"object.entity" : {"name" : "Subscriber" , "children" : [{"field.string" : {"name" : "x" }}]}},
67+ ]}})
68+ out = tmp_path / "out"
69+ out .mkdir ()
70+ (out / "__init__.py" ).write_text ("# hand written package init\n VERSION = '1'\n " )
71+ result = run_gen (GenConfig (out_dir = str (out )), root , generators = [entity_model ()])
72+ statuses = {Path (p ).name : s for p , s in result .files }
73+ assert statuses ["__init__.py" ] == "refused"
74+ assert "hand written package init" in (out / "__init__.py" ).read_text () # untouched
3075
3176
3277def test_run_gen_skips_unsafe_names_with_warning (tmp_path : Path ) -> None :
@@ -49,7 +94,8 @@ def test_run_gen_refuses_handwritten_file(tmp_path: Path) -> None:
4994 out .mkdir ()
5095 (out / "Subscriber.py" ).write_text ("# hand written, no marker\n x = 1\n " )
5196 result = run_gen (GenConfig (out_dir = str (out )), root , generators = [entity_model ()])
52- assert [w [1 ] for w in result .files ] == ["refused" ]
97+ statuses = {Path (p ).name : s for p , s in result .files }
98+ assert statuses ["Subscriber.py" ] == "refused"
5399 assert any ("Refused to overwrite" in w for w in result .warnings )
54100 assert "hand written" in (out / "Subscriber.py" ).read_text () # untouched
55101
0 commit comments