masster 0.4.19__py3-none-any.whl → 0.4.21__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of masster might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: masster
3
- Version: 0.4.19
3
+ Version: 0.4.21
4
4
  Summary: Mass spectrometry data analysis package
5
5
  Project-URL: homepage, https://github.com/zamboni-lab/masster
6
6
  Project-URL: repository, https://github.com/zamboni-lab/masster
@@ -1,9 +1,8 @@
1
- masster/__init__.py,sha256=HHjKhCjkAc98LhoQfu4C6L-W2vfTEc1iXaPTxxcl_4A,800
2
- masster/_version.py,sha256=Kro6JvBTMqNf6tOgI2r5d4TbaZIIR85ax7tdT3uQKL8,257
1
+ masster/__init__.py,sha256=ueZ224WPNRRjQEYTaQUol818nwQgJwB93HbEfmtPRmg,1041
2
+ masster/_version.py,sha256=y5IX-RaakVoxIcxnpOMo4HnIGk-qPigff8Q07QC6yJU,257
3
3
  masster/chromatogram.py,sha256=iYpdv8C17zVnlWvOFgAn9ns2uFGiF-GgoYf5QVVAbHs,19319
4
- masster/logger.py,sha256=W50V_uh8RSYwGxDrDFhOuj5jpu2tKJyt_16lMw9kQwA,14755
5
- masster/spectrum.py,sha256=_upC_g2N9gwTaflXAugs9pSXpKUmzbIehofDordk7WI,47718
6
- masster/wizard.py,sha256=jMLHy4cXgNEE_-vshFmA7BNEByhfA6tV7O91jhiMYuw,48054
4
+ masster/logger.py,sha256=tR65N23zfrNpcZNbZm2ot_Aual9XrGB1MWjLrovZkMs,16749
5
+ masster/spectrum.py,sha256=XJSUrqXZSzfpWnD8v5IMClXMRZLKLYIk014qaMOS9_k,49738
7
6
  masster/data/dda/20250530_VH_IQX_KW_RP_HSST3_100mm_12min_pos_v4_DDA_OT_C-MiLUT_QC_dil2_01_20250602151849.sample5,sha256=LdJMF8uLoDm9ixZNHBoOzBH6hX7NGY7vTvqa2Pzetb8,6539174
8
7
  masster/data/dda/20250530_VH_IQX_KW_RP_HSST3_100mm_12min_pos_v4_DDA_OT_C-MiLUT_QC_dil3_01_20250602150634.sample5,sha256=hWUfslGoOTiQw59jENSBXP4sa6DdkbOi40FJ68ep61Q,6956773
9
8
  masster/data/dda/20250530_VH_IQX_KW_RP_HSST3_100mm_12min_pos_v4_MS1_C-MiLUT_C008_v6_r38_01.sample5,sha256=dSd2cIgYYdRcNSzkhqlZCeWKi3x8Hhhcx8BFMuiVG4c,11382948
@@ -19,17 +18,17 @@ masster/lib/__init__.py,sha256=TcePNx3SYZHz6763TL9Sg4gUNXaRWjlrOtyS6vsu-hg,178
19
18
  masster/lib/lib.py,sha256=mxUYBCBmkSBZB82557smSHCS25BAusuCewvW8zwsLGg,27130
20
19
  masster/sample/__init__.py,sha256=HL0m1ept0PMAYUCQtDDnkdOS12IFl6oLAq4TZQz83uY,170
21
20
  masster/sample/adducts.py,sha256=jdtkkiMFeObRv3myluUx--IfpRsEq3-hPgkCb2VUxy4,32590
22
- masster/sample/h5.py,sha256=7NJeErlIHwC2Qh3nchusLZJWjBGue9zExAx08C89qhg,111889
21
+ masster/sample/h5.py,sha256=B0gAmhrnoFoybotqsqiT8s-PkeZWUdIQfI-4cnM52Zc,115430
23
22
  masster/sample/helpers.py,sha256=JhzFpNh7j7YVUibIMuPQ50hBcGDEBCaBbmwA3Z5OhgM,41336
24
23
  masster/sample/lib.py,sha256=E-j9c3Wd8f9a-H8xj7CAOwlA8KcyXPoFyYm3c8r7LtI,33755
25
- masster/sample/load.py,sha256=pBBcmHC6ev_fuqhUjTBNt6QghURg8tkSXr2VShbJK9k,50987
24
+ masster/sample/load.py,sha256=TqBuDPrNgIotR-mL475AfDZntsW0JjYcy5AovVKRZxY,51560
26
25
  masster/sample/parameters.py,sha256=Gg2KcuNbV_wZ_Wwv93QlM5J19ji0oSIvZLPV1NoBmq0,4456
27
- masster/sample/plot.py,sha256=abLnG0Bk75vqSGQz6uA3uTK3IE9N-s687ZH-n8Mhdzg,82757
28
- masster/sample/processing.py,sha256=lCHRv290oAFOxe_zR5GMi4FdxodjJh1rj2uLWy_wHnc,49771
26
+ masster/sample/plot.py,sha256=bQlEXCLQQWpUV88vGtftW9WAVwDKZ4k7TBirV9cO54w,82573
27
+ masster/sample/processing.py,sha256=A1u5u7lGG0HR_ciUhJFmmwgugher7_AZQopNnbu65Bs,55910
29
28
  masster/sample/quant.py,sha256=tHNjvUFTdehKR31BXBZnVsBxMD9XJHgaltITOjr71uE,7562
30
- masster/sample/sample.py,sha256=689fPI3JmMDrprv_q_JVt5CsCwcRgSR7MxS3OmHK2tA,20234
31
- masster/sample/sample5_schema.json,sha256=voVB6z0TaIJwU-_SPUEYWKH7mKC16ycTe1nW6gODYP8,3916
32
- masster/sample/save.py,sha256=XZl5ITYdOjojYFOoUZ-0ygVSPH1kT5Va6e8NyuTRNAI,32500
29
+ masster/sample/sample.py,sha256=uQP5DLdsRSC2YwZZvspsL9rgl_HefB-oxrL2dpgg_fc,19788
30
+ masster/sample/sample5_schema.json,sha256=H5e2T6rHIDzul2kp_yP-ILUUWUpW08wP2pEQjMR0nSk,3977
31
+ masster/sample/save.py,sha256=MfgHGiR2ofLyVp_rP9FIu7mUG3A6PEZHSscMypSTH7M,36425
33
32
  masster/sample/sciex.py,sha256=vnbxsq_qnAQVuzcpziP1o3IC4kM5amGBcPmC2TAuDLw,46319
34
33
  masster/sample/defaults/__init__.py,sha256=A09AOP44cxD_oYohyt7XFUho0zndRcrzVD4DUaGnKH4,447
35
34
  masster/sample/defaults/find_adducts_def.py,sha256=Bu2KiBJRxD0SAnOPNMm_Nk-6fx6QYoRXjFNGzz-0_o0,13570
@@ -38,18 +37,18 @@ masster/sample/defaults/find_ms2_def.py,sha256=KTELMAnioGLYbhzAwOgK14TZqboPEvzeB
38
37
  masster/sample/defaults/get_spectrum_def.py,sha256=o62p31PhGd-LiIkTOzKQhwPtnO2AtQDHcPu-O-YoQPs,11460
39
38
  masster/sample/defaults/sample_def.py,sha256=keoXyMyrm_iLgbYqfIbqCpJ3XHBVlNwCNmb5iMQL0iY,14579
40
39
  masster/study/__init__.py,sha256=55axdFuqRX4aXtJ8ocnhcLB32fNtmmJpCi58moO0r4g,237
41
- masster/study/export.py,sha256=L-YOUGSgVeTprYnrQxaN0qC8MRqUdDQ0D4o2h7HLi2Q,54813
42
- masster/study/h5.py,sha256=LiVGUAtULyPpZIUmKVJSaV38huJb8FsKOUWBOqiv0QU,82363
43
- masster/study/helpers.py,sha256=M5_q8O5tuFchKPW04PTuj3X335lDA2VZqcs4D8ZQJEk,158604
40
+ masster/study/export.py,sha256=CKrmje4_cQAJnQjQsB5u3mXkvDDbxKkAJO8e_MoeB38,59270
41
+ masster/study/h5.py,sha256=eINlVmcJuntwbkkZHwzm10c63Kg7zib49vkzLDj1PyU,84790
42
+ masster/study/helpers.py,sha256=6nDTNlsZbZWf9L6D5qzK2TUO2y7UBq51Ftj8N4bkIAk,160260
44
43
  masster/study/id.py,sha256=6NUBBKZCFOU1wlDKM0eXQeOIStSZCRNJ_3x7ZaIHzmM,55263
45
44
  masster/study/load.py,sha256=CQQY_7BzagE3oQTdDlqNyfuMdVWIAft-M4a2WCFnxp0,70695
46
- masster/study/merge.py,sha256=Xk7Zt6x0p_myjWQXuzXbXSlwXPSujWjMPowaqnEEmWQ,118778
45
+ masster/study/merge.py,sha256=3R_Dg6l2mnJUu3gFVAgrAN5hFSQyfHbqYPmc2cUfJqQ,159232
47
46
  masster/study/parameters.py,sha256=0elaF7YspTsB7qyajWAbRNL2VfKlGz5GJLifmO8IGkk,3276
48
- masster/study/plot.py,sha256=SimX-IlqISEItAnTBsx4xsdYHRAevfN41cCENVns1lw,88236
49
- masster/study/processing.py,sha256=u1MSRKTzcqHNz_dClSUSfgTxkNRdBLXtVyO5LXuW_uk,41031
50
- masster/study/save.py,sha256=YCvp4xhnG16sNXaT2mFDBoCrIMub0Es61B97qLo0maw,6705
51
- masster/study/study.py,sha256=LO_hbJOOCZzeA3uterPKImFgPG6fCNQKMSVMtEwW3DU,38815
52
- masster/study/study5_schema.json,sha256=c0w24QdHak01m04I1VPu97KvF2468FcaqROhf6pmLk4,7507
47
+ masster/study/plot.py,sha256=G9eStCUPxJTHrQk9TZpivk5rYxO1vbu5Yba6rP8NELM,90649
48
+ masster/study/processing.py,sha256=WOcBdQ1agayASLkrtJ9GfUT0mgCJZVNnbuT77-J-KDY,52011
49
+ masster/study/save.py,sha256=BANh9F1s-q7MclO1Mq_-v4xQyHeloEgmoPgRDVc-9aE,9037
50
+ masster/study/study.py,sha256=rk-pJNg80N6xbROa9fqPfwVxFgzL_FLoSUNOTYeD5E0,40116
51
+ masster/study/study5_schema.json,sha256=ghBeAXFS4a4Uavdn6TUVs9GaR1QOTnADCjQTOkN0tjU,7563
53
52
  masster/study/defaults/__init__.py,sha256=m3Z5KXGqsTdh7GjYzZoENERt39yRg0ceVRV1DeCt1P0,610
54
53
  masster/study/defaults/align_def.py,sha256=hHQbGgsOqMRHHr0Wn8Onr8XeaRz3-fFE0qGE-OMst80,20324
55
54
  masster/study/defaults/export_def.py,sha256=eXl3h4aoLX88XkHTpqahLd-QZ2gjUqrmjq8IJULXeWo,1203
@@ -63,13 +62,11 @@ masster/study/defaults/integrate_def.py,sha256=Vf4SAzdBfnsSZ3IRaF0qZvWu3gMDPHdgP
63
62
  masster/study/defaults/merge_def.py,sha256=K7sfwEGfgcWU85zorbWNFaxDhqRH52pxQoKv9Jn2qhY,15030
64
63
  masster/study/defaults/study_def.py,sha256=h8dYbi9xv0sesCSQik49Z53IkskMmNtW6ixl7it5pL0,16033
65
64
  masster/wizard/README.md,sha256=mL1A3YWJZOefpJ6D0-HqGLkVRmUlOpwyVFdvJBeeoZM,14149
66
- masster/wizard/__init__.py,sha256=A9GHQvkq4lSRIA8V6AKB-TJy8s_npH8i1baUGdkw_is,364
65
+ masster/wizard/__init__.py,sha256=a2hcZnHASjfuw1lqZhZnvTR58rc33rRnoGAY_JfvGhI,683
67
66
  masster/wizard/example.py,sha256=xEZFTH9UZ8HKOm6s3JL8Js0Uw5ChnISWBHSZCL32vsM,7983
68
- masster/wizard/test_structure.py,sha256=h88gsYYCG6iDRjqPZC_r1H1T8y79j0E-K6OrwuHaSCU,1586
69
- masster/wizard/test_wizard.py,sha256=CMp1cpjH3iYYC5Fy6puF_K0kfwwk3bgOsSbUGW-t7Xk,8986
70
- masster/wizard/wizard.py,sha256=jMLHy4cXgNEE_-vshFmA7BNEByhfA6tV7O91jhiMYuw,48054
71
- masster-0.4.19.dist-info/METADATA,sha256=fcnG14G4Fbp7mOCQ3aKL0qvkuexeUUjm79P1dDpT_Kg,44207
72
- masster-0.4.19.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
73
- masster-0.4.19.dist-info/entry_points.txt,sha256=ZHguQ_vPmdbpqq2uGtmEOLJfgP-DQ1T0c07Lxh30wc8,58
74
- masster-0.4.19.dist-info/licenses/LICENSE,sha256=bx5iLIKjgAdYQ7sISn7DsfHRKkoCUm1154sJJKhgqnU,35184
75
- masster-0.4.19.dist-info/RECORD,,
67
+ masster/wizard/wizard.py,sha256=498u3rvYNC0mb0kDG7T71E8TKwMk2s1KKzHgDBn76c4,37698
68
+ masster-0.4.21.dist-info/METADATA,sha256=BuBxOoHsoKYPLa5Jy6a2SPIUNDv9uCnujAbB7ibMqJU,44207
69
+ masster-0.4.21.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
70
+ masster-0.4.21.dist-info/entry_points.txt,sha256=ZHguQ_vPmdbpqq2uGtmEOLJfgP-DQ1T0c07Lxh30wc8,58
71
+ masster-0.4.21.dist-info/licenses/LICENSE,sha256=bx5iLIKjgAdYQ7sISn7DsfHRKkoCUm1154sJJKhgqnU,35184
72
+ masster-0.4.21.dist-info/RECORD,,
@@ -1,49 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Simple test to verify the wizard module structure works correctly.
4
- """
5
-
6
- def test_wizard_module_import():
7
- """Test that the wizard module can be imported."""
8
- try:
9
- # Test direct wizard module import
10
- import sys
11
- from pathlib import Path
12
-
13
- # Add the masster directory to path
14
- masster_path = Path(__file__).parent.parent
15
- sys.path.insert(0, str(masster_path))
16
-
17
- # Import wizard directly from its module
18
- from wizard import Wizard, wizard_def
19
-
20
- print("✅ Successfully imported Wizard from wizard module")
21
- print(f"✅ wizard_def class available: {wizard_def}")
22
- print(f"✅ Wizard class available: {Wizard}")
23
-
24
- # Test creating wizard_def instance
25
- defaults = wizard_def(
26
- data_source="/test/data",
27
- study_folder="/test/output",
28
- polarity="positive"
29
- )
30
-
31
- print(f"✅ Created wizard_def instance with polarity: {defaults.polarity}")
32
- print(f"✅ Default adducts: {defaults.adducts}")
33
-
34
- return True
35
-
36
- except Exception as e:
37
- print(f"❌ Import failed: {e}")
38
- import traceback
39
- traceback.print_exc()
40
- return False
41
-
42
- if __name__ == "__main__":
43
- success = test_wizard_module_import()
44
- print("\n" + "="*50)
45
- if success:
46
- print("🎉 WIZARD MODULE STRUCTURE TEST PASSED!")
47
- else:
48
- print("❌ WIZARD MODULE STRUCTURE TEST FAILED!")
49
- print("="*50)
@@ -1,285 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Test script for the Wizard class.
4
-
5
- This script tests the basic functionality of the Wizard class without
6
- requiring actual raw data files.
7
- """
8
-
9
- import tempfile
10
- from pathlib import Path
11
- import sys
12
-
13
- # Add masster to path if needed
14
- sys.path.insert(0, str(Path(__file__).parent.parent))
15
-
16
- from masster import Wizard, wizard_def
17
-
18
-
19
- def test_wizard_initialization():
20
- """Test wizard initialization and parameter handling."""
21
- print("Testing Wizard initialization...")
22
-
23
- with tempfile.TemporaryDirectory() as temp_dir:
24
- temp_path = Path(temp_dir)
25
- data_source = temp_path / "data"
26
- study_folder = temp_path / "study"
27
-
28
- # Create directories
29
- data_source.mkdir()
30
-
31
- # Test basic initialization
32
- wizard = Wizard(
33
- data_source=str(data_source),
34
- study_folder=str(study_folder),
35
- polarity="positive",
36
- num_cores=2
37
- )
38
-
39
- assert wizard.polarity == "positive"
40
- assert wizard.params.num_cores == 2
41
- assert len(wizard.adducts) > 0 # Should have default adducts
42
- assert study_folder.exists() # Should create output directory
43
-
44
- print("✅ Basic initialization works")
45
-
46
- # Test parameter validation
47
- try:
48
- Wizard(
49
- data_source="", # Empty data source should fail
50
- study_folder=str(study_folder)
51
- )
52
- assert False, "Should have failed with empty data_source"
53
- except ValueError:
54
- print("✅ Parameter validation works")
55
-
56
- # Test custom parameters
57
- custom_params = wizard_def(
58
- data_source=str(data_source),
59
- study_folder=str(study_folder / "custom"),
60
- polarity="negative",
61
- num_cores=4,
62
- adducts=["H-1:-:1.0", "Cl:-:0.1"],
63
- batch_size=2,
64
- generate_plots=False
65
- )
66
-
67
- custom_wizard = Wizard(params=custom_params)
68
- assert custom_wizard.polarity == "negative"
69
- assert custom_wizard.params.batch_size == 2
70
- assert not custom_wizard.params.generate_plots
71
-
72
- print("✅ Custom parameters work")
73
-
74
-
75
- def test_file_discovery():
76
- """Test file discovery functionality."""
77
- print("\nTesting file discovery...")
78
-
79
- with tempfile.TemporaryDirectory() as temp_dir:
80
- temp_path = Path(temp_dir)
81
- data_source = temp_path / "data"
82
- study_folder = temp_path / "study"
83
-
84
- # Create test directory structure
85
- data_source.mkdir()
86
- (data_source / "subdir").mkdir()
87
-
88
- # Create mock files
89
- test_files = [
90
- "sample1.wiff",
91
- "sample2.raw",
92
- "sample3.mzML",
93
- "blank.wiff", # Should be skipped
94
- "QC_test.raw", # Should be skipped
95
- "subdir/sample4.wiff",
96
- ]
97
-
98
- for filename in test_files:
99
- file_path = data_source / filename
100
- file_path.parent.mkdir(parents=True, exist_ok=True)
101
- file_path.write_text("mock file content")
102
-
103
- # Create wizard
104
- wizard = Wizard(
105
- data_source=str(data_source),
106
- study_folder=str(study_folder),
107
- polarity="positive"
108
- )
109
-
110
- # Test file discovery
111
- found_files = wizard.discover_files()
112
- found_names = [f.name for f in found_files]
113
-
114
- # Should find sample files but skip blanks and QC
115
- assert "sample1.wiff" in found_names
116
- assert "sample2.raw" in found_names
117
- assert "sample3.mzML" in found_names
118
- assert "sample4.wiff" in found_names # From subdirectory
119
- assert "blank.wiff" not in found_names # Should be skipped
120
- assert "QC_test.raw" not in found_names # Should be skipped
121
-
122
- print(f"✅ Found {len(found_files)} files, correctly filtered")
123
-
124
- # Test without subdirectory search
125
- wizard.params.search_subfolders = False
126
- found_files_no_sub = wizard.discover_files()
127
- found_names_no_sub = [f.name for f in found_files_no_sub]
128
-
129
- assert "sample4.wiff" not in found_names_no_sub # Should not find in subdir
130
- assert len(found_files_no_sub) < len(found_files)
131
-
132
- print("✅ Subdirectory search control works")
133
-
134
-
135
- def test_wizard_status():
136
- """Test status monitoring and checkpointing."""
137
- print("\nTesting status monitoring...")
138
-
139
- with tempfile.TemporaryDirectory() as temp_dir:
140
- temp_path = Path(temp_dir)
141
- data_source = temp_path / "data"
142
- study_folder = temp_path / "study"
143
-
144
- data_source.mkdir()
145
-
146
- wizard = Wizard(
147
- data_source=str(data_source),
148
- study_folder=str(study_folder),
149
- polarity="positive"
150
- )
151
-
152
- # Test initial status
153
- status = wizard.get_status()
154
- assert status["current_step"] == "initialized"
155
- assert status["processed_files"] == 0
156
- assert not status["study_loaded"]
157
-
158
- print("✅ Initial status correct")
159
-
160
- # Test status update
161
- wizard.current_step = "converting_to_sample5"
162
- wizard.processed_files = ["file1.wiff", "file2.raw"]
163
-
164
- status = wizard.get_status()
165
- assert status["current_step"] == "converting_to_sample5"
166
- assert status["processed_files"] == 2
167
-
168
- print("✅ Status updates work")
169
-
170
- # Test checkpoint save/load
171
- wizard._save_checkpoint()
172
- checkpoint_file = wizard.checkpoint_file
173
- assert checkpoint_file.exists()
174
-
175
- print("✅ Checkpoint saving works")
176
-
177
- # Create new wizard and test checkpoint loading
178
- new_wizard = Wizard(
179
- data_source=str(data_source),
180
- study_folder=str(study_folder),
181
- polarity="positive",
182
- resume_enabled=True
183
- )
184
-
185
- # Should load from checkpoint
186
- assert len(new_wizard.processed_files) == 2
187
- assert new_wizard.current_step == "converting_to_sample5"
188
-
189
- print("✅ Checkpoint loading works")
190
-
191
-
192
- def test_defaults_and_validation():
193
- """Test default parameter classes and validation."""
194
- print("\nTesting parameter defaults and validation...")
195
-
196
- # Test wizard_def defaults
197
- defaults = wizard_def()
198
-
199
- # Should set polarity-specific adducts
200
- assert len(defaults.adducts) > 0
201
-
202
- # Test polarity switching
203
- neg_defaults = wizard_def(polarity="negative")
204
- pos_defaults = wizard_def(polarity="positive")
205
-
206
- # Should have different adducts
207
- assert neg_defaults.adducts != pos_defaults.adducts
208
-
209
- print("✅ Polarity-specific defaults work")
210
-
211
- # Test parameter validation
212
- defaults = wizard_def(
213
- data_source="/test/path",
214
- study_folder="/test/output",
215
- num_cores=999 # Should be capped to available cores
216
- )
217
-
218
- import multiprocessing
219
- max_cores = multiprocessing.cpu_count()
220
- assert defaults.num_cores <= max_cores
221
-
222
- print("✅ Parameter validation works")
223
-
224
-
225
- def test_logging_setup():
226
- """Test logging configuration."""
227
- print("\nTesting logging setup...")
228
-
229
- with tempfile.TemporaryDirectory() as temp_dir:
230
- temp_path = Path(temp_dir)
231
- data_source = temp_path / "data"
232
- study_folder = temp_path / "study"
233
-
234
- data_source.mkdir()
235
-
236
- wizard = Wizard(
237
- data_source=str(data_source),
238
- study_folder=str(study_folder),
239
- polarity="positive",
240
- log_to_file=True,
241
- log_level="DEBUG"
242
- )
243
-
244
- # Test logging
245
- wizard._log_progress("Test message")
246
-
247
- # Check log files exist
248
- assert wizard.log_file.exists()
249
-
250
- # Check log content
251
- log_content = wizard.log_file.read_text()
252
- assert "Test message" in log_content
253
-
254
- print("✅ Logging setup works")
255
-
256
-
257
- def main():
258
- """Run all tests."""
259
- print("=" * 50)
260
- print("WIZARD CLASS TESTS")
261
- print("=" * 50)
262
-
263
- try:
264
- test_wizard_initialization()
265
- test_file_discovery()
266
- test_wizard_status()
267
- test_defaults_and_validation()
268
- test_logging_setup()
269
-
270
- print("\n" + "=" * 50)
271
- print("🎉 ALL TESTS PASSED!")
272
- print("=" * 50)
273
-
274
- except Exception as e:
275
- print(f"\n❌ TEST FAILED: {e}")
276
- import traceback
277
- traceback.print_exc()
278
- return False
279
-
280
- return True
281
-
282
-
283
- if __name__ == "__main__":
284
- success = main()
285
- sys.exit(0 if success else 1)