Skip to content

Commit 7d2ed52

Browse files
authored
Change test_mode to an app property (#2327)
Modifies `test_mode` from being an flag passed through the entire system, to a property of the app that is added during finalisation, and then propagates automatically with the app configuration.
1 parent fc6b250 commit 7d2ed52

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+408
-501
lines changed

changes/2327.misc.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Changed `test_mode` to an app property

src/briefcase/commands/base.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ def __init__(
143143
self,
144144
console: Console,
145145
tools: ToolCache = None,
146-
apps: dict = None,
146+
apps: dict[str, AppConfig] = None,
147147
base_path: Path = None,
148148
data_path: Path = None,
149149
is_clone: bool = False,
@@ -631,7 +631,7 @@ def finalize_app_config(self, app: AppConfig):
631631
:param app: The app configuration to finalize.
632632
"""
633633

634-
def finalize(self, app: AppConfig | None = None):
634+
def finalize(self, app: AppConfig | None = None, test_mode: bool = False):
635635
"""Finalize Briefcase configuration.
636636
637637
This will:
@@ -648,13 +648,10 @@ def finalize(self, app: AppConfig | None = None):
648648
self.verify_host()
649649
self.verify_tools()
650650

651-
if app is None:
652-
for app in self.apps.values():
653-
if hasattr(app, "__draft__"):
654-
self.finalize_app_config(app)
655-
delattr(app, "__draft__")
656-
else:
651+
apps = self.apps.values() if app is None else [app]
652+
for app in apps:
657653
if hasattr(app, "__draft__"):
654+
app.test_mode = test_mode
658655
self.finalize_app_config(app)
659656
delattr(app, "__draft__")
660657

src/briefcase/commands/build.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ def _build_app(
4040
update_support: bool,
4141
update_stub: bool,
4242
no_update: bool,
43-
test_mode: bool,
4443
**options,
4544
) -> dict | None:
4645
"""Internal method to invoke a build on a single app. Ensures the app exists,
@@ -56,18 +55,17 @@ def _build_app(
5655
:param update_support: Should the application support be updated?
5756
:param update_stub: Should the stub binary be updated?
5857
:param no_update: Should automated updates be disabled?
59-
:param test_mode: Is the app being build in test mode?
6058
"""
6159
if not self.bundle_path(app).exists():
62-
state = self.create_command(app, test_mode=test_mode, **options)
60+
state = self.create_command(app, **options)
6361
elif (
6462
update # An explicit update has been requested
6563
or update_requirements # An explicit update of requirements has been requested
6664
or update_resources # An explicit update of resources has been requested
6765
or update_support # An explicit update of app support has been requested
6866
or update_stub # An explicit update of the stub binary has been requested
6967
or (
70-
test_mode and not no_update
68+
app.test_mode and not no_update
7169
) # Test mode, but updates have not been disabled
7270
):
7371
state = self.update_command(
@@ -76,17 +74,16 @@ def _build_app(
7674
update_resources=update_resources,
7775
update_support=update_support,
7876
update_stub=update_stub,
79-
test_mode=test_mode,
8077
**options,
8178
)
8279
else:
8380
state = None
8481

8582
self.verify_app(app)
8683

87-
state = self.build_app(app, test_mode=test_mode, **full_options(state, options))
84+
state = self.build_app(app, **full_options(state, options))
8885

89-
qualifier = " (test mode)" if test_mode else ""
86+
qualifier = " (test mode)" if app.test_mode else ""
9087
self.console.info(
9188
f"Built {self.binary_path(app).relative_to(self.base_path)}{qualifier}",
9289
prefix=app.app_name,
@@ -132,7 +129,7 @@ def __call__(
132129

133130
# Confirm host compatibility, that all required tools are available,
134131
# and that the app configuration is finalized.
135-
self.finalize(app)
132+
self.finalize(app, test_mode)
136133

137134
if app_name:
138135
try:
@@ -156,7 +153,6 @@ def __call__(
156153
update_support=update_support,
157154
update_stub=update_stub,
158155
no_update=no_update,
159-
test_mode=test_mode,
160156
**full_options(state, options),
161157
)
162158

src/briefcase/commands/create.py

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,7 @@ def _install_app_requirements(
670670
else:
671671
self.console.info("No application requirements.")
672672

673-
def install_app_requirements(self, app: AppConfig, test_mode: bool):
673+
def install_app_requirements(self, app: AppConfig):
674674
"""Handle requirements for the app.
675675
676676
This will result in either (in preferential order):
@@ -679,16 +679,13 @@ def install_app_requirements(self, app: AppConfig, test_mode: bool):
679679
* requirements being installed with pip into the location specified
680680
by the ``app_packages_path`` in the template path index.
681681
682-
If ``test_mode`` is True, the test requirements will also be installed.
683-
684682
If the path index doesn't specify either of the path index entries,
685683
an error is raised.
686684
687685
:param app: The config object for the app
688-
:param test_mode: Should the test requirements be installed?
689686
"""
690687
requires = app.requires.copy() if app.requires else []
691-
if test_mode and app.test_requires:
688+
if app.test_mode and app.test_requires:
692689
requires.extend(app.test_requires)
693690

694691
try:
@@ -717,11 +714,10 @@ def install_app_requirements(self, app: AppConfig, test_mode: bool):
717714
"`app_requirements_path` or `app_packages_path`"
718715
) from e
719716

720-
def install_app_code(self, app: AppConfig, test_mode: bool):
717+
def install_app_code(self, app: AppConfig):
721718
"""Install the application code into the bundle.
722719
723720
:param app: The config object for the app
724-
:param test_mode: Should the application test code also be installed?
725721
"""
726722
# Remove existing app folder if it exists
727723
app_path = self.app_path(app)
@@ -730,7 +726,7 @@ def install_app_code(self, app: AppConfig, test_mode: bool):
730726
self.tools.os.mkdir(app_path)
731727

732728
sources = app.sources.copy() if app.sources else []
733-
if test_mode and app.test_sources:
729+
if app.test_mode and app.test_sources:
734730
sources.extend(app.test_sources)
735731

736732
# Install app code.
@@ -912,11 +908,10 @@ def cleanup_app_content(self, app: AppConfig):
912908
self.console.verbose(f"Removing {relative_path}")
913909
path.unlink()
914910

915-
def create_app(self, app: AppConfig, test_mode: bool = False, **options):
911+
def create_app(self, app: AppConfig, **options):
916912
"""Create an application bundle.
917913
918914
:param app: The config object for the app
919-
:param test_mode: Should the app be updated in test mode? (default: False)
920915
"""
921916
if not app.supported:
922917
raise UnsupportedPlatform(self.platform)
@@ -957,10 +952,10 @@ def create_app(self, app: AppConfig, test_mode: bool = False, **options):
957952
self.verify_app(app)
958953

959954
self.console.info("Installing application code...", prefix=app.app_name)
960-
self.install_app_code(app=app, test_mode=test_mode)
955+
self.install_app_code(app=app)
961956

962957
self.console.info("Installing requirements...", prefix=app.app_name)
963-
self.install_app_requirements(app=app, test_mode=test_mode)
958+
self.install_app_requirements(app=app)
964959

965960
self.console.info("Installing application resources...", prefix=app.app_name)
966961
self.install_app_resources(app=app)

src/briefcase/commands/dev.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -114,18 +114,16 @@ def run_dev_app(
114114
self,
115115
app: AppConfig,
116116
env: dict,
117-
test_mode: bool,
118117
passthrough: list[str],
119118
**options,
120119
):
121120
"""Run the app in the dev environment.
122121
123122
:param app: The config object for the app
124123
:param env: environment dictionary for sub command
125-
:param test_mode: Run the test suite, rather than the app?
126124
:param passthrough: A list of arguments to pass to the app
127125
"""
128-
main_module = app.main_module(test_mode)
126+
main_module = app.main_module()
129127

130128
# Add in the environment settings to get Python in the state we want.
131129
env.update(self.DEV_ENVIRONMENT)
@@ -145,7 +143,7 @@ def run_dev_app(
145143
# Console apps must operate in non-streaming mode so that console input can
146144
# be handled correctly. However, if we're in test mode, we *must* stream so
147145
# that we can see the test exit sentinel
148-
if app.console_app and not test_mode:
146+
if app.console_app and not app.test_mode:
149147
self.console.info("=" * 75)
150148
self.tools.subprocess.run(
151149
cmdline,
@@ -170,16 +168,15 @@ def run_dev_app(
170168
self._stream_app_logs(
171169
app,
172170
popen=app_popen,
173-
test_mode=test_mode,
174171
clean_output=False,
175172
)
176173

177-
def get_environment(self, app, test_mode: bool):
174+
def get_environment(self, app: AppConfig):
178175
# Create a shell environment where PYTHONPATH points to the source
179176
# directories described by the app config.
180177
env = {
181178
"PYTHONPATH": os.pathsep.join(
182-
os.fsdecode(Path.cwd() / path) for path in app.PYTHONPATH(test_mode)
179+
os.fsdecode(Path.cwd() / path) for path in app.PYTHONPATH()
183180
)
184181
}
185182

@@ -223,7 +220,7 @@ def __call__(
223220
)
224221
# Confirm host compatibility, that all required tools are available,
225222
# and that the app configuration is finalized.
226-
self.finalize(app)
223+
self.finalize(app, test_mode)
227224

228225
self.verify_app(app)
229226

@@ -243,17 +240,16 @@ def __call__(
243240
write_dist_info(app, dist_info_path)
244241

245242
if run_app:
246-
if test_mode:
243+
if app.test_mode:
247244
self.console.info(
248245
"Running test suite in dev environment...", prefix=app.app_name
249246
)
250247
else:
251248
self.console.info("Starting in dev mode...", prefix=app.app_name)
252-
env = self.get_environment(app, test_mode=test_mode)
249+
env = self.get_environment(app)
253250
return self.run_dev_app(
254251
app,
255252
env,
256-
test_mode=test_mode,
257253
passthrough=[] if passthrough is None else passthrough,
258254
**options,
259255
)

src/briefcase/commands/run.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ def _stream_app_logs(
130130
self,
131131
app: AppConfig,
132132
popen,
133-
test_mode=False,
134133
clean_filter=None,
135134
clean_output=False,
136135
stop_func=lambda: False,
@@ -143,7 +142,6 @@ def _stream_app_logs(
143142
:param app: The app to be launched
144143
:param popen: The Popen object for the stream we are monitoring; this Popen
145144
process will be closed after log streaming completes.
146-
:param test_mode: Are we launching in test mode?
147145
:param clean_filter: The log cleaning filter to use; see ``LogFilter``
148146
for details.
149147
:param clean_output: Should the cleaned output be presented to the user?
@@ -179,7 +177,7 @@ def _stream_app_logs(
179177

180178
# If we're in test mode, and log streaming ends,
181179
# check for the status of the test suite.
182-
if test_mode:
180+
if app.test_mode:
183181
if log_filter.returncode == 0:
184182
self.console.info("Test suite passed!", prefix=app.app_name)
185183
else:
@@ -220,14 +218,13 @@ def add_options(self, parser):
220218
self._add_update_options(parser, context_label=" before running")
221219
self._add_test_options(parser, context_label="Run")
222220

223-
def _prepare_app_kwargs(self, app: AppConfig, test_mode: bool):
221+
def _prepare_app_kwargs(self, app: AppConfig):
224222
"""Prepare the kwargs for running an app as a log stream.
225223
226224
This won't be used by every backend; but it's a sufficiently common default that
227225
it's been factored out.
228226
229227
:param app: The app to be launched
230-
:param test_mode: Are we launching in test mode?
231228
:returns: A dictionary of additional arguments to pass to the Popen
232229
"""
233230
args = {}
@@ -237,10 +234,10 @@ def _prepare_app_kwargs(self, app: AppConfig, test_mode: bool):
237234
if self.console.is_debug:
238235
env["BRIEFCASE_DEBUG"] = "1"
239236

240-
if test_mode:
237+
if app.test_mode:
241238
# In test mode, set a BRIEFCASE_MAIN_MODULE environment variable
242239
# to override the module at startup
243-
env["BRIEFCASE_MAIN_MODULE"] = app.main_module(test_mode)
240+
env["BRIEFCASE_MAIN_MODULE"] = app.main_module()
244241
self.console.info("Starting test_suite...", prefix=app.app_name)
245242
else:
246243
self.console.info("Starting app...", prefix=app.app_name)
@@ -290,7 +287,7 @@ def __call__(
290287

291288
# Confirm host compatibility, that all required tools are available,
292289
# and that the app configuration is finalized.
293-
self.finalize(app)
290+
self.finalize(app, test_mode)
294291

295292
template_file = self.bundle_path(app)
296293
exec_file = self.binary_executable_path(app)
@@ -303,7 +300,7 @@ def __call__(
303300
or update_stub # An explicit update of the stub binary has been requested
304301
or (not exec_file.exists()) # Executable binary doesn't exist yet
305302
or (
306-
test_mode and not no_update
303+
app.test_mode and not no_update
307304
) # Test mode, but updates have not been disabled
308305
):
309306
state = self.build_command(
@@ -314,7 +311,6 @@ def __call__(
314311
update_support=update_support,
315312
update_stub=update_stub,
316313
no_update=no_update,
317-
test_mode=test_mode,
318314
**options,
319315
)
320316
else:
@@ -324,7 +320,6 @@ def __call__(
324320

325321
state = self.run_app(
326322
app,
327-
test_mode=test_mode,
328323
passthrough=[] if passthrough is None else passthrough,
329324
**full_options(state, options),
330325
)

src/briefcase/commands/update.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ def update_app(
3232
update_resources: bool,
3333
update_support: bool,
3434
update_stub: bool,
35-
test_mode: bool,
3635
**options,
3736
) -> dict | None:
3837
"""Update an existing application bundle.
@@ -42,7 +41,6 @@ def update_app(
4241
:param update_resources: Should extra resources be updated?
4342
:param update_support: Should app support be updated?
4443
:param update_stub: Should stub binary be updated?
45-
:param test_mode: Should the app be updated in test mode?
4644
"""
4745

4846
if not self.bundle_path(app).exists():
@@ -54,11 +52,11 @@ def update_app(
5452
self.verify_app(app)
5553

5654
self.console.info("Updating application code...", prefix=app.app_name)
57-
self.install_app_code(app=app, test_mode=test_mode)
55+
self.install_app_code(app=app)
5856

5957
if update_requirements:
6058
self.console.info("Updating requirements...", prefix=app.app_name)
61-
self.install_app_requirements(app=app, test_mode=test_mode)
59+
self.install_app_requirements(app=app)
6260

6361
if update_resources:
6462
self.console.info("Updating application resources...", prefix=app.app_name)
@@ -100,7 +98,7 @@ def __call__(
10098
) -> dict | None:
10199
# Confirm host compatibility, that all required tools are available,
102100
# and that the app configuration is finalized.
103-
self.finalize(app)
101+
self.finalize(app, test_mode)
104102

105103
if app_name:
106104
try:
@@ -122,7 +120,6 @@ def __call__(
122120
update_resources=update_resources,
123121
update_support=update_support,
124122
update_stub=update_stub,
125-
test_mode=test_mode,
126123
**full_options(state, options),
127124
)
128125

0 commit comments

Comments
 (0)