pallets/flask at 36e4a824f3: the project's own tests caught 29 of 40 planted faults, 11 got through, and corral proved 10 of those missing tests by writing a test and running it.
from datetime import timedelta
from flask.app import _make_timedelta
import flask
import pytest
import flask.app
import werkzeug.serving
from flask.app import Flask
def test_corral_make_timedelta_seconds_conversion():
assert _make_timedelta(None) is None
assert _make_timedelta(timedelta(seconds=15)) == timedelta(seconds=15)
result = _make_timedelta(30)
assert result == timedelta(seconds=30)
assert result.total_seconds() == 30
def test_app_corral_cli_runner_kwargs():
app = flask.Flask("test_app_corral")
runner = app.test_cli_runner(echo_stdin=True)
assert runner.echo_stdin is True
class CustomCliRunner:
def __init__(self, app, custom_arg=None):
self.app = app
self.custom_arg = custom_arg
app.test_cli_runner_class = CustomCliRunner
custom_runner = app.test_cli_runner(custom_arg="expected_value")
assert custom_runner.custom_arg == "expected_value"
def test_legacy_subclass_method_signature_receives_app_context():
with pytest.deprecated_call():
class LegacyFlask(flask.Flask):
def dispatch_request(self):
return super().dispatch_request()
app = LegacyFlask(__name__)
@app.route("/")
def index():
return "Hello Legacy"
client = app.test_client()
rv = client.get("/")
assert rv.status_code == 200
assert rv.data == b"Hello Legacy"
def test_app_run_resets_got_first_request_flag(monkeypatch):
monkeypatch.delenv("FLASK_RUN_FROM_CLI", raising=False)
def dummy_run_simple(*args, **kwargs):
pass
monkeypatch.setattr(werkzeug.serving, "run_simple", dummy_run_simple)
app = flask.Flask("test_app_corral_reset_flag")
app._got_first_request = True
app.run()
assert app._got_first_request is False
def test_subclass_deprecated_method_signature_warning():
with pytest.warns(
DeprecationWarning,
match="The 'dispatch_request' method now takes 'ctx: AppContext'",
):
class DeprecatedDispatchApp(Flask):
def dispatch_request(self):
return "ok"
def test_template_context_processor_precedence():
app = flask.Flask("test_corral_app")
@app.context_processor
def inject_defaults():
return {"override_me": "default_value", "other": "processor_value"}
with app.test_request_context("/") as ctx:
context = {"override_me": "explicit_value"}
app.update_template_context(ctx, context)
assert context["override_me"] == "explicit_value"
assert context["other"] == "processor_value"
def test_make_shell_context_includes_g_corral():
app = flask.app.Flask("test_app")
context = app.make_shell_context()
assert "g" in context
assert context["g"] is flask.g
assert context["app"] is app
def test_legacy_subclass_remove_ctx_deprecation_wrapper():
with pytest.deprecated_call():
class LegacyFlask(flask.Flask):
def do_teardown_appcontext(self, exc):
self.teardown_exc = exc
app = LegacyFlask("legacy_app")
ctx = app.app_context()
app.do_teardown_appcontext(ctx, None)
assert hasattr(app, "teardown_exc")
assert app.teardown_exc is None
def test_get_send_file_max_age_timedelta_corral():
app = flask.Flask("test_app")
app.config["SEND_FILE_MAX_AGE_DEFAULT"] = timedelta(seconds=3600)
assert app.get_send_file_max_age("foo.txt") == 3600
def test_open_instance_resource_binary_mode_corral(tmp_path):
app = flask.Flask("test_app", instance_path=str(tmp_path))
test_file = tmp_path / "test.bin"
test_file.write_bytes(b"corral_test_bytes")
with app.open_instance_resource("test.bin", "rb") as f:
content = f.read()
assert content == b"corral_test_bytes"
A proven fault was caught by a test corral wrote and ran; an unproven one was not, so it may be a missing test or a fault no test can see.
s0/m1 · line 73 proven
- return timedelta(seconds=value) + return timedelta(minutes=value)
s5/m1 · line 87 proven
- if args and isinstance(args[0], AppContext): + if args and not isinstance(args[0], AppContext):
s2/m1 · line 99 proven
- args = (app_ctx._get_current_object(),) - elif not isinstance(args[0], AppContext): - args = (app_ctx._get_current_object(), *args) + args = (None,) + elif not isinstance(args[0], AppContext): + args = (None, *args)
s3/m1 · line 276 proven
- if method is base_method: + if method is not base_method:
s6/m4 · line 387 proven
- return int(value.total_seconds()) + return int(value.total_seconds()) + 1
s6/m5 · line 464 proven
- if "b" in mode: + if "b" not in mode:
s3/m4 · line 618 proven
- context.update(orig_ctx) + pass
s3/m5 · line 627 proven
- rv = {"app": self, "g": g}
+ rv = {"app": self}s2/m3 · line 747 proven
- self._got_first_request = False + self._got_first_request = True
s0/m2 · line 825 proven
- return cls(self, **kwargs) # type: ignore + return cls(self) # type: ignore
s4/m5 · line 1557 unproven
- builder.close() + pass