mirror of
https://github.com/evennia/evennia.git
synced 2026-03-20 23:06:31 +01:00
1974 lines
No EOL
252 KiB
HTML
1974 lines
No EOL
252 KiB
HTML
|
|
<!DOCTYPE html>
|
|
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>django.test.testcases — Evennia latest documentation</title>
|
|
<link rel="stylesheet" href="../../../_static/nature.css" type="text/css" />
|
|
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
|
|
<link rel="stylesheet" type="text/css" href="../../../_static/pygments.css?v=d75fae25" />
|
|
<link rel="stylesheet" type="text/css" href="../../../_static/nature.css?v=245aff17" />
|
|
<script id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
|
|
<script src="../../../_static/documentation_options.js?v=c6e86fd7"></script>
|
|
<script src="../../../_static/doctools.js?v=9bcbadda"></script>
|
|
<script src="../../../_static/sphinx_highlight.js?v=dc90522c"></script>
|
|
<link rel="index" title="Index" href="../../../genindex.html" />
|
|
<link rel="search" title="Search" href="../../../search.html" />
|
|
</head><body>
|
|
|
|
|
|
|
|
|
|
<div class="related" role="navigation" aria-label="related navigation">
|
|
<h3>Navigation</h3>
|
|
<ul>
|
|
<li class="right" style="margin-right: 10px">
|
|
<a href="../../../genindex.html" title="General Index"
|
|
accesskey="I">index</a></li>
|
|
<li class="right" >
|
|
<a href="../../../py-modindex.html" title="Python Module Index"
|
|
>modules</a> |</li>
|
|
<li class="nav-item nav-item-0"><a href="../../../index.html">Evennia latest</a> »</li>
|
|
<li class="nav-item nav-item-1"><a href="../../index.html" accesskey="U">Module code</a> »</li>
|
|
<li class="nav-item nav-item-this"><a href="">django.test.testcases</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="document">
|
|
|
|
<div class="documentwrapper">
|
|
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
|
<div class="sphinxsidebarwrapper">
|
|
<search id="searchbox" style="display: none" role="search">
|
|
<h3 id="searchlabel">Quick search</h3>
|
|
<div class="searchformwrapper">
|
|
<form class="search" action="../../../search.html" method="get">
|
|
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
|
<input type="submit" value="Go" />
|
|
</form>
|
|
</div>
|
|
</search>
|
|
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Links</h3>
|
|
<ul>
|
|
<li><a href="https://www.evennia.com/docs/latest/index.html">Documentation Top</a> </li>
|
|
<li><a href="https://www.evennia.com">Evennia Home</a> </li>
|
|
<li><a href="https://github.com/evennia/evennia">Github</a> </li>
|
|
<li><a href="http://games.evennia.com">Game Index</a> </li>
|
|
<li>
|
|
<a href="https://discord.gg/AJJpcRUhtF">Discord</a> -
|
|
<a href="https://github.com/evennia/evennia/discussions">Discussions</a> -
|
|
<a href="https://evennia.blogspot.com/">Blog</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div class="bodywrapper">
|
|
<div class="body" role="main">
|
|
|
|
<h1>Source code for django.test.testcases</h1><div class="highlight"><pre>
|
|
<span></span><span class="kn">import</span><span class="w"> </span><span class="nn">difflib</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">json</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">logging</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">pickle</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">posixpath</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">sys</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">threading</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">unittest</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">collections</span><span class="w"> </span><span class="kn">import</span> <span class="n">Counter</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">contextlib</span><span class="w"> </span><span class="kn">import</span> <span class="n">contextmanager</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">copy</span><span class="w"> </span><span class="kn">import</span> <span class="n">copy</span><span class="p">,</span> <span class="n">deepcopy</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">difflib</span><span class="w"> </span><span class="kn">import</span> <span class="n">get_close_matches</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">functools</span><span class="w"> </span><span class="kn">import</span> <span class="n">wraps</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">unittest</span><span class="w"> </span><span class="kn">import</span> <span class="n">mock</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">unittest.suite</span><span class="w"> </span><span class="kn">import</span> <span class="n">_DebugResult</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">unittest.util</span><span class="w"> </span><span class="kn">import</span> <span class="n">safe_repr</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">urllib.parse</span><span class="w"> </span><span class="kn">import</span> <span class="p">(</span>
|
|
<span class="n">parse_qsl</span><span class="p">,</span>
|
|
<span class="n">unquote</span><span class="p">,</span>
|
|
<span class="n">urlencode</span><span class="p">,</span>
|
|
<span class="n">urljoin</span><span class="p">,</span>
|
|
<span class="n">urlparse</span><span class="p">,</span>
|
|
<span class="n">urlsplit</span><span class="p">,</span>
|
|
<span class="n">urlunparse</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">urllib.request</span><span class="w"> </span><span class="kn">import</span> <span class="n">url2pathname</span>
|
|
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">asgiref.sync</span><span class="w"> </span><span class="kn">import</span> <span class="n">async_to_sync</span><span class="p">,</span> <span class="n">iscoroutinefunction</span>
|
|
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.apps</span><span class="w"> </span><span class="kn">import</span> <span class="n">apps</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.conf</span><span class="w"> </span><span class="kn">import</span> <span class="n">settings</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.core</span><span class="w"> </span><span class="kn">import</span> <span class="n">mail</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.core.exceptions</span><span class="w"> </span><span class="kn">import</span> <span class="n">ImproperlyConfigured</span><span class="p">,</span> <span class="n">ValidationError</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.core.files</span><span class="w"> </span><span class="kn">import</span> <span class="n">locks</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.core.handlers.wsgi</span><span class="w"> </span><span class="kn">import</span> <span class="n">WSGIHandler</span><span class="p">,</span> <span class="n">get_path_info</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.core.management</span><span class="w"> </span><span class="kn">import</span> <span class="n">call_command</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.core.management.color</span><span class="w"> </span><span class="kn">import</span> <span class="n">no_style</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.core.management.sql</span><span class="w"> </span><span class="kn">import</span> <span class="n">emit_post_migrate_signal</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.core.servers.basehttp</span><span class="w"> </span><span class="kn">import</span> <span class="n">ThreadedWSGIServer</span><span class="p">,</span> <span class="n">WSGIRequestHandler</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.core.signals</span><span class="w"> </span><span class="kn">import</span> <span class="n">setting_changed</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.db</span><span class="w"> </span><span class="kn">import</span> <span class="n">DEFAULT_DB_ALIAS</span><span class="p">,</span> <span class="n">connection</span><span class="p">,</span> <span class="n">connections</span><span class="p">,</span> <span class="n">transaction</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.db.backends.base.base</span><span class="w"> </span><span class="kn">import</span> <span class="n">NO_DB_ALIAS</span><span class="p">,</span> <span class="n">BaseDatabaseWrapper</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.forms.fields</span><span class="w"> </span><span class="kn">import</span> <span class="n">CharField</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.http</span><span class="w"> </span><span class="kn">import</span> <span class="n">QueryDict</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.http.request</span><span class="w"> </span><span class="kn">import</span> <span class="n">split_domain_port</span><span class="p">,</span> <span class="n">validate_host</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.test.client</span><span class="w"> </span><span class="kn">import</span> <span class="n">AsyncClient</span><span class="p">,</span> <span class="n">Client</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.test.html</span><span class="w"> </span><span class="kn">import</span> <span class="n">HTMLParseError</span><span class="p">,</span> <span class="n">parse_html</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.test.signals</span><span class="w"> </span><span class="kn">import</span> <span class="n">template_rendered</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.test.utils</span><span class="w"> </span><span class="kn">import</span> <span class="p">(</span>
|
|
<span class="n">CaptureQueriesContext</span><span class="p">,</span>
|
|
<span class="n">ContextList</span><span class="p">,</span>
|
|
<span class="n">compare_xml</span><span class="p">,</span>
|
|
<span class="n">modify_settings</span><span class="p">,</span>
|
|
<span class="n">override_settings</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.utils.functional</span><span class="w"> </span><span class="kn">import</span> <span class="n">classproperty</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.utils.version</span><span class="w"> </span><span class="kn">import</span> <span class="n">PY311</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.views.static</span><span class="w"> </span><span class="kn">import</span> <span class="n">serve</span>
|
|
|
|
<span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s2">"django.test"</span><span class="p">)</span>
|
|
|
|
<span class="n">__all__</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="s2">"TestCase"</span><span class="p">,</span>
|
|
<span class="s2">"TransactionTestCase"</span><span class="p">,</span>
|
|
<span class="s2">"SimpleTestCase"</span><span class="p">,</span>
|
|
<span class="s2">"skipIfDBFeature"</span><span class="p">,</span>
|
|
<span class="s2">"skipUnlessDBFeature"</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">PY311</span><span class="p">:</span>
|
|
<span class="c1"># Backport of unittest.case._enter_context() from Python 3.11.</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_enter_context</span><span class="p">(</span><span class="n">cm</span><span class="p">,</span> <span class="n">addcleanup</span><span class="p">):</span>
|
|
<span class="c1"># Look up the special methods on the type to match the with statement.</span>
|
|
<span class="bp">cls</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">cm</span><span class="p">)</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">enter</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="fm">__enter__</span>
|
|
<span class="n">exit</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="fm">__exit__</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"'</span><span class="si">{</span><span class="bp">cls</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">cls</span><span class="o">.</span><span class="vm">__qualname__</span><span class="si">}</span><span class="s2">' object does not support the "</span>
|
|
<span class="sa">f</span><span class="s2">"context manager protocol"</span>
|
|
<span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
|
|
<span class="n">result</span> <span class="o">=</span> <span class="n">enter</span><span class="p">(</span><span class="n">cm</span><span class="p">)</span>
|
|
<span class="n">addcleanup</span><span class="p">(</span><span class="n">exit</span><span class="p">,</span> <span class="n">cm</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">result</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">to_list</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Put value into a list if it's not already one."""</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span>
|
|
<span class="n">value</span> <span class="o">=</span> <span class="p">[</span><span class="n">value</span><span class="p">]</span>
|
|
<span class="k">return</span> <span class="n">value</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">is_pickable</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Returns true if the object can be dumped and loaded through the pickle</span>
|
|
<span class="sd"> module.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">pickle</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">pickle</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">obj</span><span class="p">))</span>
|
|
<span class="k">except</span> <span class="p">(</span><span class="ne">AttributeError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">,</span> <span class="n">pickle</span><span class="o">.</span><span class="n">PickleError</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="kc">False</span>
|
|
<span class="k">return</span> <span class="kc">True</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assert_and_parse_html</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">html</span><span class="p">,</span> <span class="n">user_msg</span><span class="p">,</span> <span class="n">msg</span><span class="p">):</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">dom</span> <span class="o">=</span> <span class="n">parse_html</span><span class="p">(</span><span class="n">html</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="n">HTMLParseError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
|
<span class="n">standardMsg</span> <span class="o">=</span> <span class="s2">"</span><span class="si">%s</span><span class="se">\n</span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">fail</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_formatMessage</span><span class="p">(</span><span class="n">user_msg</span><span class="p">,</span> <span class="n">standardMsg</span><span class="p">))</span>
|
|
<span class="k">return</span> <span class="n">dom</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_AssertNumQueriesContext</span><span class="p">(</span><span class="n">CaptureQueriesContext</span><span class="p">):</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">test_case</span><span class="p">,</span> <span class="n">num</span><span class="p">,</span> <span class="n">connection</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">test_case</span> <span class="o">=</span> <span class="n">test_case</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">num</span> <span class="o">=</span> <span class="n">num</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">connection</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exc_type</span><span class="p">,</span> <span class="n">exc_value</span><span class="p">,</span> <span class="n">traceback</span><span class="p">):</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__exit__</span><span class="p">(</span><span class="n">exc_type</span><span class="p">,</span> <span class="n">exc_value</span><span class="p">,</span> <span class="n">traceback</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">exc_type</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span>
|
|
<span class="n">executed</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">test_case</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span>
|
|
<span class="n">executed</span><span class="p">,</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">num</span><span class="p">,</span>
|
|
<span class="s2">"</span><span class="si">%d</span><span class="s2"> queries executed, </span><span class="si">%d</span><span class="s2"> expected</span><span class="se">\n</span><span class="s2">Captured queries were:</span><span class="se">\n</span><span class="si">%s</span><span class="s2">"</span>
|
|
<span class="o">%</span> <span class="p">(</span>
|
|
<span class="n">executed</span><span class="p">,</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">num</span><span class="p">,</span>
|
|
<span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
|
|
<span class="s2">"</span><span class="si">%d</span><span class="s2">. </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">query</span><span class="p">[</span><span class="s2">"sql"</span><span class="p">])</span>
|
|
<span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">query</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">captured_queries</span><span class="p">,</span> <span class="n">start</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
|
|
<span class="p">),</span>
|
|
<span class="p">),</span>
|
|
<span class="p">)</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_AssertTemplateUsedContext</span><span class="p">:</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">test_case</span><span class="p">,</span> <span class="n">template_name</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span> <span class="n">count</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">test_case</span> <span class="o">=</span> <span class="n">test_case</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">template_name</span> <span class="o">=</span> <span class="n">template_name</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">msg_prefix</span> <span class="o">=</span> <span class="n">msg_prefix</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">count</span> <span class="o">=</span> <span class="n">count</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">rendered_templates</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">context</span> <span class="o">=</span> <span class="n">ContextList</span><span class="p">()</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">on_template_render</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sender</span><span class="p">,</span> <span class="n">signal</span><span class="p">,</span> <span class="n">template</span><span class="p">,</span> <span class="n">context</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">rendered_templates</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">template</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">context</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">copy</span><span class="p">(</span><span class="n">context</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">test</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">test_case</span><span class="o">.</span><span class="n">_assert_template_used</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">template_name</span><span class="p">,</span>
|
|
<span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">name</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">rendered_templates</span> <span class="k">if</span> <span class="n">t</span><span class="o">.</span><span class="n">name</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">],</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">msg_prefix</span><span class="p">,</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">count</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__enter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="n">template_rendered</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">on_template_render</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="bp">self</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exc_type</span><span class="p">,</span> <span class="n">exc_value</span><span class="p">,</span> <span class="n">traceback</span><span class="p">):</span>
|
|
<span class="n">template_rendered</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">on_template_render</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">exc_type</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">test</span><span class="p">()</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_AssertTemplateNotUsedContext</span><span class="p">(</span><span class="n">_AssertTemplateUsedContext</span><span class="p">):</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">test</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="n">rendered_template_names</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="n">t</span><span class="o">.</span><span class="n">name</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">rendered_templates</span> <span class="k">if</span> <span class="n">t</span><span class="o">.</span><span class="n">name</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
|
|
<span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">test_case</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">template_name</span> <span class="ow">in</span> <span class="n">rendered_template_names</span><span class="p">,</span>
|
|
<span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">msg_prefix</span><span class="si">}</span><span class="s2">Template '</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">template_name</span><span class="si">}</span><span class="s2">' was used "</span>
|
|
<span class="sa">f</span><span class="s2">"unexpectedly in rendering the response"</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">DatabaseOperationForbidden</span><span class="p">(</span><span class="ne">AssertionError</span><span class="p">):</span>
|
|
<span class="k">pass</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_DatabaseFailure</span><span class="p">:</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">wrapped</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">wrapped</span> <span class="o">=</span> <span class="n">wrapped</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="n">message</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="n">DatabaseOperationForbidden</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">message</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">SimpleTestCase</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
|
|
<span class="c1"># The class we'll use for the test client self.client.</span>
|
|
<span class="c1"># Can be overridden in derived classes.</span>
|
|
<span class="n">client_class</span> <span class="o">=</span> <span class="n">Client</span>
|
|
<span class="n">async_client_class</span> <span class="o">=</span> <span class="n">AsyncClient</span>
|
|
<span class="n">_overridden_settings</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">_modified_settings</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="n">databases</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
<span class="n">_disallowed_database_msg</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="s2">"Database </span><span class="si">%(operation)s</span><span class="s2"> to </span><span class="si">%(alias)r</span><span class="s2"> are not allowed in SimpleTestCase "</span>
|
|
<span class="s2">"subclasses. Either subclass TestCase or TransactionTestCase to ensure "</span>
|
|
<span class="s2">"proper test isolation or add </span><span class="si">%(alias)r</span><span class="s2"> to </span><span class="si">%(test)s</span><span class="s2">.databases to silence "</span>
|
|
<span class="s2">"this failure."</span>
|
|
<span class="p">)</span>
|
|
<span class="n">_disallowed_connection_methods</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="p">(</span><span class="s2">"connect"</span><span class="p">,</span> <span class="s2">"connections"</span><span class="p">),</span>
|
|
<span class="p">(</span><span class="s2">"temporary_connection"</span><span class="p">,</span> <span class="s2">"connections"</span><span class="p">),</span>
|
|
<span class="p">(</span><span class="s2">"cursor"</span><span class="p">,</span> <span class="s2">"queries"</span><span class="p">),</span>
|
|
<span class="p">(</span><span class="s2">"chunked_cursor"</span><span class="p">,</span> <span class="s2">"queries"</span><span class="p">),</span>
|
|
<span class="p">]</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">setUpClass</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">setUpClass</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_overridden_settings</span><span class="p">:</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">enterClassContext</span><span class="p">(</span><span class="n">override_settings</span><span class="p">(</span><span class="o">**</span><span class="bp">cls</span><span class="o">.</span><span class="n">_overridden_settings</span><span class="p">))</span>
|
|
<span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_modified_settings</span><span class="p">:</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">enterClassContext</span><span class="p">(</span><span class="n">modify_settings</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">_modified_settings</span><span class="p">))</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">_add_databases_failures</span><span class="p">()</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">addClassCleanup</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">_remove_databases_failures</span><span class="p">)</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_validate_databases</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">databases</span> <span class="o">==</span> <span class="s2">"__all__"</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="nb">frozenset</span><span class="p">(</span><span class="n">connections</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">alias</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">databases</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">alias</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">connections</span><span class="p">:</span>
|
|
<span class="n">message</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="s2">"</span><span class="si">%s</span><span class="s2">.</span><span class="si">%s</span><span class="s2">.databases refers to </span><span class="si">%r</span><span class="s2"> which is not defined in "</span>
|
|
<span class="s2">"settings.DATABASES."</span>
|
|
<span class="o">%</span> <span class="p">(</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="vm">__module__</span><span class="p">,</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="vm">__qualname__</span><span class="p">,</span>
|
|
<span class="n">alias</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="p">)</span>
|
|
<span class="n">close_matches</span> <span class="o">=</span> <span class="n">get_close_matches</span><span class="p">(</span><span class="n">alias</span><span class="p">,</span> <span class="nb">list</span><span class="p">(</span><span class="n">connections</span><span class="p">))</span>
|
|
<span class="k">if</span> <span class="n">close_matches</span><span class="p">:</span>
|
|
<span class="n">message</span> <span class="o">+=</span> <span class="s2">" Did you mean </span><span class="si">%r</span><span class="s2">?"</span> <span class="o">%</span> <span class="n">close_matches</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">raise</span> <span class="n">ImproperlyConfigured</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="nb">frozenset</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">databases</span><span class="p">)</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_add_databases_failures</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">databases</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_validate_databases</span><span class="p">()</span>
|
|
<span class="k">for</span> <span class="n">alias</span> <span class="ow">in</span> <span class="n">connections</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">alias</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">databases</span><span class="p">:</span>
|
|
<span class="k">continue</span>
|
|
<span class="n">connection</span> <span class="o">=</span> <span class="n">connections</span><span class="p">[</span><span class="n">alias</span><span class="p">]</span>
|
|
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">operation</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_disallowed_connection_methods</span><span class="p">:</span>
|
|
<span class="n">message</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_disallowed_database_msg</span> <span class="o">%</span> <span class="p">{</span>
|
|
<span class="s2">"test"</span><span class="p">:</span> <span class="s2">"</span><span class="si">%s</span><span class="s2">.</span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="vm">__module__</span><span class="p">,</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__qualname__</span><span class="p">),</span>
|
|
<span class="s2">"alias"</span><span class="p">:</span> <span class="n">alias</span><span class="p">,</span>
|
|
<span class="s2">"operation"</span><span class="p">:</span> <span class="n">operation</span><span class="p">,</span>
|
|
<span class="p">}</span>
|
|
<span class="n">method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">connection</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
|
|
<span class="nb">setattr</span><span class="p">(</span><span class="n">connection</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">_DatabaseFailure</span><span class="p">(</span><span class="n">method</span><span class="p">,</span> <span class="n">message</span><span class="p">))</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">enterClassContext</span><span class="p">(</span>
|
|
<span class="n">mock</span><span class="o">.</span><span class="n">patch</span><span class="o">.</span><span class="n">object</span><span class="p">(</span>
|
|
<span class="n">BaseDatabaseWrapper</span><span class="p">,</span>
|
|
<span class="s2">"ensure_connection"</span><span class="p">,</span>
|
|
<span class="n">new</span><span class="o">=</span><span class="bp">cls</span><span class="o">.</span><span class="n">ensure_connection_patch_method</span><span class="p">(),</span>
|
|
<span class="p">)</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_remove_databases_failures</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="k">for</span> <span class="n">alias</span> <span class="ow">in</span> <span class="n">connections</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">alias</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">databases</span><span class="p">:</span>
|
|
<span class="k">continue</span>
|
|
<span class="n">connection</span> <span class="o">=</span> <span class="n">connections</span><span class="p">[</span><span class="n">alias</span><span class="p">]</span>
|
|
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">_</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_disallowed_connection_methods</span><span class="p">:</span>
|
|
<span class="n">method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">connection</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
|
|
<span class="nb">setattr</span><span class="p">(</span><span class="n">connection</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">method</span><span class="o">.</span><span class="n">wrapped</span><span class="p">)</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">ensure_connection_patch_method</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="n">real_ensure_connection</span> <span class="o">=</span> <span class="n">BaseDatabaseWrapper</span><span class="o">.</span><span class="n">ensure_connection</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">patched_ensure_connection</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="p">(</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">connection</span> <span class="ow">is</span> <span class="kc">None</span>
|
|
<span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">alias</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">databases</span>
|
|
<span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">alias</span> <span class="o">!=</span> <span class="n">NO_DB_ALIAS</span>
|
|
<span class="c1"># Dynamically created connections are always allowed.</span>
|
|
<span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">alias</span> <span class="ow">in</span> <span class="n">connections</span>
|
|
<span class="p">):</span>
|
|
<span class="c1"># Connection has not yet been established, but the alias is not allowed.</span>
|
|
<span class="n">message</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_disallowed_database_msg</span> <span class="o">%</span> <span class="p">{</span>
|
|
<span class="s2">"test"</span><span class="p">:</span> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">cls</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">cls</span><span class="o">.</span><span class="vm">__qualname__</span><span class="si">}</span><span class="s2">"</span><span class="p">,</span>
|
|
<span class="s2">"alias"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">alias</span><span class="p">,</span>
|
|
<span class="s2">"operation"</span><span class="p">:</span> <span class="s2">"threaded connections"</span><span class="p">,</span>
|
|
<span class="p">}</span>
|
|
<span class="k">return</span> <span class="n">_DatabaseFailure</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ensure_connection</span><span class="p">,</span> <span class="n">message</span><span class="p">)()</span>
|
|
|
|
<span class="n">real_ensure_connection</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
|
|
|
<span class="k">return</span> <span class="n">patched_ensure_connection</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">result</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Wrapper around default __call__ method to perform common Django test</span>
|
|
<span class="sd"> set up. This means that user-defined TestCases aren't required to</span>
|
|
<span class="sd"> include a call to super().setUp().</span>
|
|
<span class="sd"> """</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_setup_and_call</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__getstate__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Make SimpleTestCase picklable for parallel tests using subtests.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">state</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="vm">__dict__</span>
|
|
<span class="c1"># _outcome and _subtest cannot be tested on picklability, since they</span>
|
|
<span class="c1"># contain the TestCase itself, leading to an infinite recursion.</span>
|
|
<span class="k">if</span> <span class="n">state</span><span class="p">[</span><span class="s2">"_outcome"</span><span class="p">]:</span>
|
|
<span class="n">pickable_state</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"_outcome"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> <span class="s2">"_subtest"</span><span class="p">:</span> <span class="kc">None</span><span class="p">}</span>
|
|
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">state</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">pickable_state</span> <span class="ow">or</span> <span class="ow">not</span> <span class="n">is_pickable</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
|
|
<span class="k">continue</span>
|
|
<span class="n">pickable_state</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
|
|
<span class="k">return</span> <span class="n">pickable_state</span>
|
|
|
|
<span class="k">return</span> <span class="n">state</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">debug</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Perform the same as __call__(), without catching the exception."""</span>
|
|
<span class="n">debug_result</span> <span class="o">=</span> <span class="n">_DebugResult</span><span class="p">()</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_setup_and_call</span><span class="p">(</span><span class="n">debug_result</span><span class="p">,</span> <span class="n">debug</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_setup_and_call</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">result</span><span class="p">,</span> <span class="n">debug</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Perform the following in order: pre-setup, run test, post-teardown,</span>
|
|
<span class="sd"> skipping pre/post hooks if test is set to be skipped.</span>
|
|
|
|
<span class="sd"> If debug=True, reraise any errors in setup and use super().debug()</span>
|
|
<span class="sd"> instead of __call__() to run the test.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">testMethod</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_testMethodName</span><span class="p">)</span>
|
|
<span class="n">skipped</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span> <span class="s2">"__unittest_skip__"</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span> <span class="ow">or</span> <span class="nb">getattr</span><span class="p">(</span>
|
|
<span class="n">testMethod</span><span class="p">,</span> <span class="s2">"__unittest_skip__"</span><span class="p">,</span> <span class="kc">False</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># Convert async test methods.</span>
|
|
<span class="k">if</span> <span class="n">iscoroutinefunction</span><span class="p">(</span><span class="n">testMethod</span><span class="p">):</span>
|
|
<span class="nb">setattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_testMethodName</span><span class="p">,</span> <span class="n">async_to_sync</span><span class="p">(</span><span class="n">testMethod</span><span class="p">))</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">skipped</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_pre_setup</span><span class="p">()</span>
|
|
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">debug</span><span class="p">:</span>
|
|
<span class="k">raise</span>
|
|
<span class="n">result</span><span class="o">.</span><span class="n">addError</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">())</span>
|
|
<span class="k">return</span>
|
|
<span class="k">if</span> <span class="n">debug</span><span class="p">:</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">debug</span><span class="p">()</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__call__</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">skipped</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_post_teardown</span><span class="p">()</span>
|
|
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">debug</span><span class="p">:</span>
|
|
<span class="k">raise</span>
|
|
<span class="n">result</span><span class="o">.</span><span class="n">addError</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">())</span>
|
|
<span class="k">return</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_pre_setup</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Perform pre-test setup:</span>
|
|
<span class="sd"> * Create a test client.</span>
|
|
<span class="sd"> * Clear the mail test outbox.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">client</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">client_class</span><span class="p">()</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">async_client</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">async_client_class</span><span class="p">()</span>
|
|
<span class="n">mail</span><span class="o">.</span><span class="n">outbox</span> <span class="o">=</span> <span class="p">[]</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_post_teardown</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Perform post-test things."""</span>
|
|
<span class="k">pass</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">PY311</span><span class="p">:</span>
|
|
<span class="c1"># Backport of unittest.TestCase.enterClassContext() from Python 3.11.</span>
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">enterClassContext</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">cm</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">_enter_context</span><span class="p">(</span><span class="n">cm</span><span class="p">,</span> <span class="bp">cls</span><span class="o">.</span><span class="n">addClassCleanup</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">settings</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> A context manager that temporarily sets a setting and reverts to the</span>
|
|
<span class="sd"> original value when exiting the context.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="n">override_settings</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">modify_settings</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> A context manager that temporarily applies changes a list setting and</span>
|
|
<span class="sd"> reverts back to the original value when exiting the context.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="n">modify_settings</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assertRedirects</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="p">,</span>
|
|
<span class="n">response</span><span class="p">,</span>
|
|
<span class="n">expected_url</span><span class="p">,</span>
|
|
<span class="n">status_code</span><span class="o">=</span><span class="mi">302</span><span class="p">,</span>
|
|
<span class="n">target_status_code</span><span class="o">=</span><span class="mi">200</span><span class="p">,</span>
|
|
<span class="n">msg_prefix</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
|
|
<span class="n">fetch_redirect_response</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
|
|
<span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Assert that a response redirected to a specific URL and that the</span>
|
|
<span class="sd"> redirect URL can be loaded.</span>
|
|
|
|
<span class="sd"> Won't work for external links since it uses the test client to do a</span>
|
|
<span class="sd"> request (use fetch_redirect_response=False to check such links without</span>
|
|
<span class="sd"> fetching them).</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">msg_prefix</span><span class="p">:</span>
|
|
<span class="n">msg_prefix</span> <span class="o">+=</span> <span class="s2">": "</span>
|
|
|
|
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="s2">"redirect_chain"</span><span class="p">):</span>
|
|
<span class="c1"># The request was a followed redirect</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span>
|
|
<span class="n">response</span><span class="o">.</span><span class="n">redirect_chain</span><span class="p">,</span>
|
|
<span class="n">msg_prefix</span>
|
|
<span class="o">+</span> <span class="p">(</span>
|
|
<span class="s2">"Response didn't redirect as expected: Response code was </span><span class="si">%d</span><span class="s2"> "</span>
|
|
<span class="s2">"(expected </span><span class="si">%d</span><span class="s2">)"</span>
|
|
<span class="p">)</span>
|
|
<span class="o">%</span> <span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="p">,</span> <span class="n">status_code</span><span class="p">),</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span>
|
|
<span class="n">response</span><span class="o">.</span><span class="n">redirect_chain</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">],</span>
|
|
<span class="n">status_code</span><span class="p">,</span>
|
|
<span class="n">msg_prefix</span>
|
|
<span class="o">+</span> <span class="p">(</span>
|
|
<span class="s2">"Initial response didn't redirect as expected: Response code was "</span>
|
|
<span class="s2">"</span><span class="si">%d</span><span class="s2"> (expected </span><span class="si">%d</span><span class="s2">)"</span>
|
|
<span class="p">)</span>
|
|
<span class="o">%</span> <span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">redirect_chain</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">],</span> <span class="n">status_code</span><span class="p">),</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="n">url</span><span class="p">,</span> <span class="n">status_code</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">redirect_chain</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span>
|
|
<span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="p">,</span>
|
|
<span class="n">target_status_code</span><span class="p">,</span>
|
|
<span class="n">msg_prefix</span>
|
|
<span class="o">+</span> <span class="p">(</span>
|
|
<span class="s2">"Response didn't redirect as expected: Final Response code was </span><span class="si">%d</span><span class="s2"> "</span>
|
|
<span class="s2">"(expected </span><span class="si">%d</span><span class="s2">)"</span>
|
|
<span class="p">)</span>
|
|
<span class="o">%</span> <span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="p">,</span> <span class="n">target_status_code</span><span class="p">),</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># Not a followed redirect</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span>
|
|
<span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="p">,</span>
|
|
<span class="n">status_code</span><span class="p">,</span>
|
|
<span class="n">msg_prefix</span>
|
|
<span class="o">+</span> <span class="p">(</span>
|
|
<span class="s2">"Response didn't redirect as expected: Response code was </span><span class="si">%d</span><span class="s2"> "</span>
|
|
<span class="s2">"(expected </span><span class="si">%d</span><span class="s2">)"</span>
|
|
<span class="p">)</span>
|
|
<span class="o">%</span> <span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="p">,</span> <span class="n">status_code</span><span class="p">),</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="n">url</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">url</span>
|
|
<span class="n">scheme</span><span class="p">,</span> <span class="n">netloc</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">query</span><span class="p">,</span> <span class="n">fragment</span> <span class="o">=</span> <span class="n">urlsplit</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
|
|
|
|
<span class="c1"># Prepend the request path to handle relative path redirects.</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">path</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"/"</span><span class="p">):</span>
|
|
<span class="n">url</span> <span class="o">=</span> <span class="n">urljoin</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">request</span><span class="p">[</span><span class="s2">"PATH_INFO"</span><span class="p">],</span> <span class="n">url</span><span class="p">)</span>
|
|
<span class="n">path</span> <span class="o">=</span> <span class="n">urljoin</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">request</span><span class="p">[</span><span class="s2">"PATH_INFO"</span><span class="p">],</span> <span class="n">path</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">fetch_redirect_response</span><span class="p">:</span>
|
|
<span class="c1"># netloc might be empty, or in cases where Django tests the</span>
|
|
<span class="c1"># HTTP scheme, the convention is for netloc to be 'testserver'.</span>
|
|
<span class="c1"># Trust both as "internal" URLs here.</span>
|
|
<span class="n">domain</span><span class="p">,</span> <span class="n">port</span> <span class="o">=</span> <span class="n">split_domain_port</span><span class="p">(</span><span class="n">netloc</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">domain</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">validate_host</span><span class="p">(</span><span class="n">domain</span><span class="p">,</span> <span class="n">settings</span><span class="o">.</span><span class="n">ALLOWED_HOSTS</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
|
|
<span class="s2">"The test client is unable to fetch remote URLs (got </span><span class="si">%s</span><span class="s2">). "</span>
|
|
<span class="s2">"If the host is served by Django, add '</span><span class="si">%s</span><span class="s2">' to ALLOWED_HOSTS. "</span>
|
|
<span class="s2">"Otherwise, use "</span>
|
|
<span class="s2">"assertRedirects(..., fetch_redirect_response=False)."</span>
|
|
<span class="o">%</span> <span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">domain</span><span class="p">)</span>
|
|
<span class="p">)</span>
|
|
<span class="c1"># Get the redirection page, using the same client that was used</span>
|
|
<span class="c1"># to obtain the original response.</span>
|
|
<span class="n">extra</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">extra</span> <span class="ow">or</span> <span class="p">{}</span>
|
|
<span class="n">headers</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">headers</span> <span class="ow">or</span> <span class="p">{}</span>
|
|
<span class="n">redirect_response</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
|
|
<span class="n">path</span><span class="p">,</span>
|
|
<span class="n">QueryDict</span><span class="p">(</span><span class="n">query</span><span class="p">),</span>
|
|
<span class="n">secure</span><span class="o">=</span><span class="p">(</span><span class="n">scheme</span> <span class="o">==</span> <span class="s2">"https"</span><span class="p">),</span>
|
|
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
|
|
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span>
|
|
<span class="n">redirect_response</span><span class="o">.</span><span class="n">status_code</span><span class="p">,</span>
|
|
<span class="n">target_status_code</span><span class="p">,</span>
|
|
<span class="n">msg_prefix</span>
|
|
<span class="o">+</span> <span class="p">(</span>
|
|
<span class="s2">"Couldn't retrieve redirection page '</span><span class="si">%s</span><span class="s2">': response code was </span><span class="si">%d</span><span class="s2"> "</span>
|
|
<span class="s2">"(expected </span><span class="si">%d</span><span class="s2">)"</span>
|
|
<span class="p">)</span>
|
|
<span class="o">%</span> <span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">redirect_response</span><span class="o">.</span><span class="n">status_code</span><span class="p">,</span> <span class="n">target_status_code</span><span class="p">),</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertURLEqual</span><span class="p">(</span>
|
|
<span class="n">url</span><span class="p">,</span>
|
|
<span class="n">expected_url</span><span class="p">,</span>
|
|
<span class="n">msg_prefix</span>
|
|
<span class="o">+</span> <span class="s2">"Response redirected to '</span><span class="si">%s</span><span class="s2">', expected '</span><span class="si">%s</span><span class="s2">'"</span> <span class="o">%</span> <span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">expected_url</span><span class="p">),</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assertURLEqual</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url1</span><span class="p">,</span> <span class="n">url2</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="o">=</span><span class="s2">""</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Assert that two URLs are the same, ignoring the order of query string</span>
|
|
<span class="sd"> parameters except for parameters with the same name.</span>
|
|
|
|
<span class="sd"> For example, /path/?x=1&y=2 is equal to /path/?y=2&x=1, but</span>
|
|
<span class="sd"> /path/?a=1&a=2 isn't equal to /path/?a=2&a=1.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">normalize</span><span class="p">(</span><span class="n">url</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Sort the URL's query string parameters."""</span>
|
|
<span class="n">url</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">url</span><span class="p">)</span> <span class="c1"># Coerce reverse_lazy() URLs.</span>
|
|
<span class="n">scheme</span><span class="p">,</span> <span class="n">netloc</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">params</span><span class="p">,</span> <span class="n">query</span><span class="p">,</span> <span class="n">fragment</span> <span class="o">=</span> <span class="n">urlparse</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
|
|
<span class="n">query_parts</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">parse_qsl</span><span class="p">(</span><span class="n">query</span><span class="p">))</span>
|
|
<span class="k">return</span> <span class="n">urlunparse</span><span class="p">(</span>
|
|
<span class="p">(</span><span class="n">scheme</span><span class="p">,</span> <span class="n">netloc</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">params</span><span class="p">,</span> <span class="n">urlencode</span><span class="p">(</span><span class="n">query_parts</span><span class="p">),</span> <span class="n">fragment</span><span class="p">)</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">msg_prefix</span><span class="p">:</span>
|
|
<span class="n">msg_prefix</span> <span class="o">+=</span> <span class="s2">": "</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span>
|
|
<span class="n">normalize</span><span class="p">(</span><span class="n">url1</span><span class="p">),</span>
|
|
<span class="n">normalize</span><span class="p">(</span><span class="n">url2</span><span class="p">),</span>
|
|
<span class="n">msg_prefix</span> <span class="o">+</span> <span class="s2">"Expected '</span><span class="si">%s</span><span class="s2">' to equal '</span><span class="si">%s</span><span class="s2">'."</span> <span class="o">%</span> <span class="p">(</span><span class="n">url1</span><span class="p">,</span> <span class="n">url2</span><span class="p">),</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_assert_contains</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">response</span><span class="p">,</span> <span class="n">text</span><span class="p">,</span> <span class="n">status_code</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="p">,</span> <span class="n">html</span><span class="p">):</span>
|
|
<span class="c1"># If the response supports deferred rendering and hasn't been rendered</span>
|
|
<span class="c1"># yet, then ensure that it does get rendered before proceeding further.</span>
|
|
<span class="k">if</span> <span class="p">(</span>
|
|
<span class="nb">hasattr</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="s2">"render"</span><span class="p">)</span>
|
|
<span class="ow">and</span> <span class="nb">callable</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">render</span><span class="p">)</span>
|
|
<span class="ow">and</span> <span class="ow">not</span> <span class="n">response</span><span class="o">.</span><span class="n">is_rendered</span>
|
|
<span class="p">):</span>
|
|
<span class="n">response</span><span class="o">.</span><span class="n">render</span><span class="p">()</span>
|
|
|
|
<span class="k">if</span> <span class="n">msg_prefix</span><span class="p">:</span>
|
|
<span class="n">msg_prefix</span> <span class="o">+=</span> <span class="s2">": "</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span>
|
|
<span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="p">,</span>
|
|
<span class="n">status_code</span><span class="p">,</span>
|
|
<span class="n">msg_prefix</span> <span class="o">+</span> <span class="s2">"Couldn't retrieve content: Response code was </span><span class="si">%d</span><span class="s2">"</span>
|
|
<span class="s2">" (expected </span><span class="si">%d</span><span class="s2">)"</span> <span class="o">%</span> <span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="p">,</span> <span class="n">status_code</span><span class="p">),</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">streaming</span><span class="p">:</span>
|
|
<span class="n">content</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">""</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">streaming_content</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">content</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">content</span>
|
|
<span class="n">content_repr</span> <span class="o">=</span> <span class="n">safe_repr</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="nb">bytes</span><span class="p">)</span> <span class="ow">or</span> <span class="n">html</span><span class="p">:</span>
|
|
<span class="n">text</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
|
|
<span class="n">content</span> <span class="o">=</span> <span class="n">content</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">charset</span><span class="p">)</span>
|
|
<span class="n">text_repr</span> <span class="o">=</span> <span class="s2">"'</span><span class="si">%s</span><span class="s2">'"</span> <span class="o">%</span> <span class="n">text</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">text_repr</span> <span class="o">=</span> <span class="nb">repr</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">html</span><span class="p">:</span>
|
|
<span class="n">content</span> <span class="o">=</span> <span class="n">assert_and_parse_html</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="p">,</span> <span class="n">content</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="s2">"Response's content is not valid HTML:"</span>
|
|
<span class="p">)</span>
|
|
<span class="n">text</span> <span class="o">=</span> <span class="n">assert_and_parse_html</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="p">,</span> <span class="n">text</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="s2">"Second argument is not valid HTML:"</span>
|
|
<span class="p">)</span>
|
|
<span class="n">real_count</span> <span class="o">=</span> <span class="n">content</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">text_repr</span><span class="p">,</span> <span class="n">real_count</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="p">,</span> <span class="n">content_repr</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assertContains</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="p">,</span> <span class="n">response</span><span class="p">,</span> <span class="n">text</span><span class="p">,</span> <span class="n">count</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">status_code</span><span class="o">=</span><span class="mi">200</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span> <span class="n">html</span><span class="o">=</span><span class="kc">False</span>
|
|
<span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Assert that a response indicates that some content was retrieved</span>
|
|
<span class="sd"> successfully, (i.e., the HTTP status code was as expected) and that</span>
|
|
<span class="sd"> ``text`` occurs ``count`` times in the content of the response.</span>
|
|
<span class="sd"> If ``count`` is None, the count doesn't matter - the assertion is true</span>
|
|
<span class="sd"> if the text occurs at least once in the response.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">text_repr</span><span class="p">,</span> <span class="n">real_count</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="p">,</span> <span class="n">content_repr</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_assert_contains</span><span class="p">(</span>
|
|
<span class="n">response</span><span class="p">,</span> <span class="n">text</span><span class="p">,</span> <span class="n">status_code</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="p">,</span> <span class="n">html</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">count</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span>
|
|
<span class="n">real_count</span><span class="p">,</span>
|
|
<span class="n">count</span><span class="p">,</span>
|
|
<span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">msg_prefix</span><span class="si">}</span><span class="s2">Found </span><span class="si">{</span><span class="n">real_count</span><span class="si">}</span><span class="s2"> instances of </span><span class="si">{</span><span class="n">text_repr</span><span class="si">}</span><span class="s2"> "</span>
|
|
<span class="sa">f</span><span class="s2">"(expected </span><span class="si">{</span><span class="n">count</span><span class="si">}</span><span class="s2">) in the following response</span><span class="se">\n</span><span class="si">{</span><span class="n">content_repr</span><span class="si">}</span><span class="s2">"</span>
|
|
<span class="p">),</span>
|
|
<span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span>
|
|
<span class="n">real_count</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">,</span>
|
|
<span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">msg_prefix</span><span class="si">}</span><span class="s2">Couldn't find </span><span class="si">{</span><span class="n">text_repr</span><span class="si">}</span><span class="s2"> in the following response</span><span class="se">\n</span><span class="s2">"</span>
|
|
<span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">content_repr</span><span class="si">}</span><span class="s2">"</span>
|
|
<span class="p">),</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assertNotContains</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="p">,</span> <span class="n">response</span><span class="p">,</span> <span class="n">text</span><span class="p">,</span> <span class="n">status_code</span><span class="o">=</span><span class="mi">200</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span> <span class="n">html</span><span class="o">=</span><span class="kc">False</span>
|
|
<span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Assert that a response indicates that some content was retrieved</span>
|
|
<span class="sd"> successfully, (i.e., the HTTP status code was as expected) and that</span>
|
|
<span class="sd"> ``text`` doesn't occur in the content of the response.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">text_repr</span><span class="p">,</span> <span class="n">real_count</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="p">,</span> <span class="n">content_repr</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_assert_contains</span><span class="p">(</span>
|
|
<span class="n">response</span><span class="p">,</span> <span class="n">text</span><span class="p">,</span> <span class="n">status_code</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="p">,</span> <span class="n">html</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span>
|
|
<span class="n">real_count</span><span class="p">,</span>
|
|
<span class="mi">0</span><span class="p">,</span>
|
|
<span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">msg_prefix</span><span class="si">}{</span><span class="n">text_repr</span><span class="si">}</span><span class="s2"> unexpectedly found in the following response"</span>
|
|
<span class="sa">f</span><span class="s2">"</span><span class="se">\n</span><span class="si">{</span><span class="n">content_repr</span><span class="si">}</span><span class="s2">"</span>
|
|
<span class="p">),</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_check_test_client_response</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">response</span><span class="p">,</span> <span class="n">attribute</span><span class="p">,</span> <span class="n">method_name</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Raise a ValueError if the given response doesn't have the required</span>
|
|
<span class="sd"> attribute.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="n">attribute</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">method_name</span><span class="si">}</span><span class="s2">() is only usable on responses fetched using "</span>
|
|
<span class="s2">"the Django test Client."</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_assert_form_error</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">form</span><span class="p">,</span> <span class="n">field</span><span class="p">,</span> <span class="n">errors</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="p">,</span> <span class="n">form_repr</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">form</span><span class="o">.</span><span class="n">is_bound</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">fail</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">msg_prefix</span><span class="si">}</span><span class="s2">The </span><span class="si">{</span><span class="n">form_repr</span><span class="si">}</span><span class="s2"> is not bound, it will never have any "</span>
|
|
<span class="sa">f</span><span class="s2">"errors."</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">field</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">field</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">form</span><span class="o">.</span><span class="n">fields</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">fail</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">msg_prefix</span><span class="si">}</span><span class="s2">The </span><span class="si">{</span><span class="n">form_repr</span><span class="si">}</span><span class="s2"> does not contain the field </span><span class="si">{</span><span class="n">field</span><span class="si">!r}</span><span class="s2">."</span>
|
|
<span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">field</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">field_errors</span> <span class="o">=</span> <span class="n">form</span><span class="o">.</span><span class="n">non_field_errors</span><span class="p">()</span>
|
|
<span class="n">failure_message</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"The non-field errors of </span><span class="si">{</span><span class="n">form_repr</span><span class="si">}</span><span class="s2"> don't match."</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">field_errors</span> <span class="o">=</span> <span class="n">form</span><span class="o">.</span><span class="n">errors</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="p">[])</span>
|
|
<span class="n">failure_message</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"The errors of field </span><span class="si">{</span><span class="n">field</span><span class="si">!r}</span><span class="s2"> on </span><span class="si">{</span><span class="n">form_repr</span><span class="si">}</span><span class="s2"> don't match."</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">field_errors</span><span class="p">,</span> <span class="n">errors</span><span class="p">,</span> <span class="n">msg_prefix</span> <span class="o">+</span> <span class="n">failure_message</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assertFormError</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">form</span><span class="p">,</span> <span class="n">field</span><span class="p">,</span> <span class="n">errors</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="o">=</span><span class="s2">""</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Assert that a field named "field" on the given form object has specific</span>
|
|
<span class="sd"> errors.</span>
|
|
|
|
<span class="sd"> errors can be either a single error message or a list of errors</span>
|
|
<span class="sd"> messages. Using errors=[] test that the field has no errors.</span>
|
|
|
|
<span class="sd"> You can pass field=None to check the form's non-field errors.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">msg_prefix</span><span class="p">:</span>
|
|
<span class="n">msg_prefix</span> <span class="o">+=</span> <span class="s2">": "</span>
|
|
<span class="n">errors</span> <span class="o">=</span> <span class="n">to_list</span><span class="p">(</span><span class="n">errors</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_assert_form_error</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">field</span><span class="p">,</span> <span class="n">errors</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="p">,</span> <span class="sa">f</span><span class="s2">"form </span><span class="si">{</span><span class="n">form</span><span class="si">!r}</span><span class="s2">"</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assertFormSetError</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">formset</span><span class="p">,</span> <span class="n">form_index</span><span class="p">,</span> <span class="n">field</span><span class="p">,</span> <span class="n">errors</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="o">=</span><span class="s2">""</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Similar to assertFormError() but for formsets.</span>
|
|
|
|
<span class="sd"> Use form_index=None to check the formset's non-form errors (in that</span>
|
|
<span class="sd"> case, you must also use field=None).</span>
|
|
<span class="sd"> Otherwise use an integer to check the formset's n-th form for errors.</span>
|
|
|
|
<span class="sd"> Other parameters are the same as assertFormError().</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">form_index</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">field</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"You must use field=None with form_index=None."</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">msg_prefix</span><span class="p">:</span>
|
|
<span class="n">msg_prefix</span> <span class="o">+=</span> <span class="s2">": "</span>
|
|
<span class="n">errors</span> <span class="o">=</span> <span class="n">to_list</span><span class="p">(</span><span class="n">errors</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">formset</span><span class="o">.</span><span class="n">is_bound</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">fail</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">msg_prefix</span><span class="si">}</span><span class="s2">The formset </span><span class="si">{</span><span class="n">formset</span><span class="si">!r}</span><span class="s2"> is not bound, it will never have "</span>
|
|
<span class="sa">f</span><span class="s2">"any errors."</span>
|
|
<span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">form_index</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">form_index</span> <span class="o">>=</span> <span class="n">formset</span><span class="o">.</span><span class="n">total_form_count</span><span class="p">():</span>
|
|
<span class="n">form_count</span> <span class="o">=</span> <span class="n">formset</span><span class="o">.</span><span class="n">total_form_count</span><span class="p">()</span>
|
|
<span class="n">form_or_forms</span> <span class="o">=</span> <span class="s2">"forms"</span> <span class="k">if</span> <span class="n">form_count</span> <span class="o">></span> <span class="mi">1</span> <span class="k">else</span> <span class="s2">"form"</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">fail</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">msg_prefix</span><span class="si">}</span><span class="s2">The formset </span><span class="si">{</span><span class="n">formset</span><span class="si">!r}</span><span class="s2"> only has </span><span class="si">{</span><span class="n">form_count</span><span class="si">}</span><span class="s2"> "</span>
|
|
<span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">form_or_forms</span><span class="si">}</span><span class="s2">."</span>
|
|
<span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">form_index</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">form_repr</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"form </span><span class="si">{</span><span class="n">form_index</span><span class="si">}</span><span class="s2"> of formset </span><span class="si">{</span><span class="n">formset</span><span class="si">!r}</span><span class="s2">"</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_assert_form_error</span><span class="p">(</span>
|
|
<span class="n">formset</span><span class="o">.</span><span class="n">forms</span><span class="p">[</span><span class="n">form_index</span><span class="p">],</span> <span class="n">field</span><span class="p">,</span> <span class="n">errors</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="p">,</span> <span class="n">form_repr</span>
|
|
<span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">failure_message</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"The non-form errors of formset </span><span class="si">{</span><span class="n">formset</span><span class="si">!r}</span><span class="s2"> don't match."</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span>
|
|
<span class="n">formset</span><span class="o">.</span><span class="n">non_form_errors</span><span class="p">(),</span> <span class="n">errors</span><span class="p">,</span> <span class="n">msg_prefix</span> <span class="o">+</span> <span class="n">failure_message</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_get_template_used</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">response</span><span class="p">,</span> <span class="n">template_name</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="p">,</span> <span class="n">method_name</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">response</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">template_name</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"response and/or template_name argument must be provided"</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">msg_prefix</span><span class="p">:</span>
|
|
<span class="n">msg_prefix</span> <span class="o">+=</span> <span class="s2">": "</span>
|
|
|
|
<span class="k">if</span> <span class="n">template_name</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">response</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_check_test_client_response</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="s2">"templates"</span><span class="p">,</span> <span class="n">method_name</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="s2">"templates"</span><span class="p">)</span> <span class="ow">or</span> <span class="p">(</span><span class="n">response</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">template_name</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">response</span><span class="p">:</span>
|
|
<span class="n">template_name</span> <span class="o">=</span> <span class="n">response</span>
|
|
<span class="n">response</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="c1"># use this template with context manager</span>
|
|
<span class="k">return</span> <span class="n">template_name</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="n">msg_prefix</span>
|
|
|
|
<span class="n">template_names</span> <span class="o">=</span> <span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">name</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">response</span><span class="o">.</span><span class="n">templates</span> <span class="k">if</span> <span class="n">t</span><span class="o">.</span><span class="n">name</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">]</span>
|
|
<span class="k">return</span> <span class="kc">None</span><span class="p">,</span> <span class="n">template_names</span><span class="p">,</span> <span class="n">msg_prefix</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_assert_template_used</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">template_name</span><span class="p">,</span> <span class="n">template_names</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="p">,</span> <span class="n">count</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">template_names</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">fail</span><span class="p">(</span><span class="n">msg_prefix</span> <span class="o">+</span> <span class="s2">"No templates used to render the response"</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span>
|
|
<span class="n">template_name</span> <span class="ow">in</span> <span class="n">template_names</span><span class="p">,</span>
|
|
<span class="n">msg_prefix</span> <span class="o">+</span> <span class="s2">"Template '</span><span class="si">%s</span><span class="s2">' was not a template used to render"</span>
|
|
<span class="s2">" the response. Actual template(s) used: </span><span class="si">%s</span><span class="s2">"</span>
|
|
<span class="o">%</span> <span class="p">(</span><span class="n">template_name</span><span class="p">,</span> <span class="s2">", "</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">template_names</span><span class="p">)),</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">count</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span>
|
|
<span class="n">template_names</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="n">template_name</span><span class="p">),</span>
|
|
<span class="n">count</span><span class="p">,</span>
|
|
<span class="n">msg_prefix</span> <span class="o">+</span> <span class="s2">"Template '</span><span class="si">%s</span><span class="s2">' was expected to be rendered </span><span class="si">%d</span><span class="s2"> "</span>
|
|
<span class="s2">"time(s) but was actually rendered </span><span class="si">%d</span><span class="s2"> time(s)."</span>
|
|
<span class="o">%</span> <span class="p">(</span><span class="n">template_name</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">template_names</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="n">template_name</span><span class="p">)),</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assertTemplateUsed</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="p">,</span> <span class="n">response</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">template_name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span> <span class="n">count</span><span class="o">=</span><span class="kc">None</span>
|
|
<span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Assert that the template with the provided name was used in rendering</span>
|
|
<span class="sd"> the response. Also usable as context manager.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">context_mgr_template</span><span class="p">,</span> <span class="n">template_names</span><span class="p">,</span> <span class="n">msg_prefix</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_template_used</span><span class="p">(</span>
|
|
<span class="n">response</span><span class="p">,</span>
|
|
<span class="n">template_name</span><span class="p">,</span>
|
|
<span class="n">msg_prefix</span><span class="p">,</span>
|
|
<span class="s2">"assertTemplateUsed"</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">context_mgr_template</span><span class="p">:</span>
|
|
<span class="c1"># Use assertTemplateUsed as context manager.</span>
|
|
<span class="k">return</span> <span class="n">_AssertTemplateUsedContext</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="p">,</span> <span class="n">context_mgr_template</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="p">,</span> <span class="n">count</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_assert_template_used</span><span class="p">(</span><span class="n">template_name</span><span class="p">,</span> <span class="n">template_names</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="p">,</span> <span class="n">count</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assertTemplateNotUsed</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">response</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">template_name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="o">=</span><span class="s2">""</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Assert that the template with the provided name was NOT used in</span>
|
|
<span class="sd"> rendering the response. Also usable as context manager.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">context_mgr_template</span><span class="p">,</span> <span class="n">template_names</span><span class="p">,</span> <span class="n">msg_prefix</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_template_used</span><span class="p">(</span>
|
|
<span class="n">response</span><span class="p">,</span>
|
|
<span class="n">template_name</span><span class="p">,</span>
|
|
<span class="n">msg_prefix</span><span class="p">,</span>
|
|
<span class="s2">"assertTemplateNotUsed"</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">context_mgr_template</span><span class="p">:</span>
|
|
<span class="c1"># Use assertTemplateNotUsed as context manager.</span>
|
|
<span class="k">return</span> <span class="n">_AssertTemplateNotUsedContext</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context_mgr_template</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="p">)</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertFalse</span><span class="p">(</span>
|
|
<span class="n">template_name</span> <span class="ow">in</span> <span class="n">template_names</span><span class="p">,</span>
|
|
<span class="n">msg_prefix</span>
|
|
<span class="o">+</span> <span class="s2">"Template '</span><span class="si">%s</span><span class="s2">' was used unexpectedly in rendering the response"</span>
|
|
<span class="o">%</span> <span class="n">template_name</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="nd">@contextmanager</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_assert_raises_or_warns_cm</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="p">,</span> <span class="n">func</span><span class="p">,</span> <span class="n">cm_attr</span><span class="p">,</span> <span class="n">expected_exception</span><span class="p">,</span> <span class="n">expected_message</span>
|
|
<span class="p">):</span>
|
|
<span class="k">with</span> <span class="n">func</span><span class="p">(</span><span class="n">expected_exception</span><span class="p">)</span> <span class="k">as</span> <span class="n">cm</span><span class="p">:</span>
|
|
<span class="k">yield</span> <span class="n">cm</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertIn</span><span class="p">(</span><span class="n">expected_message</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="nb">getattr</span><span class="p">(</span><span class="n">cm</span><span class="p">,</span> <span class="n">cm_attr</span><span class="p">)))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_assertFooMessage</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="p">,</span> <span class="n">func</span><span class="p">,</span> <span class="n">cm_attr</span><span class="p">,</span> <span class="n">expected_exception</span><span class="p">,</span> <span class="n">expected_message</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span>
|
|
<span class="p">):</span>
|
|
<span class="n">callable_obj</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">if</span> <span class="n">args</span><span class="p">:</span>
|
|
<span class="n">callable_obj</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span> <span class="o">=</span> <span class="n">args</span>
|
|
<span class="n">cm</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_assert_raises_or_warns_cm</span><span class="p">(</span>
|
|
<span class="n">func</span><span class="p">,</span> <span class="n">cm_attr</span><span class="p">,</span> <span class="n">expected_exception</span><span class="p">,</span> <span class="n">expected_message</span>
|
|
<span class="p">)</span>
|
|
<span class="c1"># Assertion used in context manager fashion.</span>
|
|
<span class="k">if</span> <span class="n">callable_obj</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">cm</span>
|
|
<span class="c1"># Assertion was passed a callable.</span>
|
|
<span class="k">with</span> <span class="n">cm</span><span class="p">:</span>
|
|
<span class="n">callable_obj</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assertRaisesMessage</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="p">,</span> <span class="n">expected_exception</span><span class="p">,</span> <span class="n">expected_message</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span>
|
|
<span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Assert that expected_message is found in the message of a raised</span>
|
|
<span class="sd"> exception.</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> expected_exception: Exception class expected to be raised.</span>
|
|
<span class="sd"> expected_message: expected error message string value.</span>
|
|
<span class="sd"> args: Function to be called and extra positional args.</span>
|
|
<span class="sd"> kwargs: Extra kwargs.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_assertFooMessage</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertRaises</span><span class="p">,</span>
|
|
<span class="s2">"exception"</span><span class="p">,</span>
|
|
<span class="n">expected_exception</span><span class="p">,</span>
|
|
<span class="n">expected_message</span><span class="p">,</span>
|
|
<span class="o">*</span><span class="n">args</span><span class="p">,</span>
|
|
<span class="o">**</span><span class="n">kwargs</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assertWarnsMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">expected_warning</span><span class="p">,</span> <span class="n">expected_message</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Same as assertRaisesMessage but for assertWarns() instead of</span>
|
|
<span class="sd"> assertRaises().</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_assertFooMessage</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertWarns</span><span class="p">,</span>
|
|
<span class="s2">"warning"</span><span class="p">,</span>
|
|
<span class="n">expected_warning</span><span class="p">,</span>
|
|
<span class="n">expected_message</span><span class="p">,</span>
|
|
<span class="o">*</span><span class="n">args</span><span class="p">,</span>
|
|
<span class="o">**</span><span class="n">kwargs</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assertFieldOutput</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="p">,</span>
|
|
<span class="n">fieldclass</span><span class="p">,</span>
|
|
<span class="n">valid</span><span class="p">,</span>
|
|
<span class="n">invalid</span><span class="p">,</span>
|
|
<span class="n">field_args</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">field_kwargs</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">empty_value</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span>
|
|
<span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Assert that a form field behaves correctly with various inputs.</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> fieldclass: the class of the field to be tested.</span>
|
|
<span class="sd"> valid: a dictionary mapping valid inputs to their expected</span>
|
|
<span class="sd"> cleaned values.</span>
|
|
<span class="sd"> invalid: a dictionary mapping invalid inputs to one or more</span>
|
|
<span class="sd"> raised error messages.</span>
|
|
<span class="sd"> field_args: the args passed to instantiate the field</span>
|
|
<span class="sd"> field_kwargs: the kwargs passed to instantiate the field</span>
|
|
<span class="sd"> empty_value: the expected clean output for inputs in empty_values</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">field_args</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">field_args</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">if</span> <span class="n">field_kwargs</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">field_kwargs</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="n">required</span> <span class="o">=</span> <span class="n">fieldclass</span><span class="p">(</span><span class="o">*</span><span class="n">field_args</span><span class="p">,</span> <span class="o">**</span><span class="n">field_kwargs</span><span class="p">)</span>
|
|
<span class="n">optional</span> <span class="o">=</span> <span class="n">fieldclass</span><span class="p">(</span><span class="o">*</span><span class="n">field_args</span><span class="p">,</span> <span class="o">**</span><span class="p">{</span><span class="o">**</span><span class="n">field_kwargs</span><span class="p">,</span> <span class="s2">"required"</span><span class="p">:</span> <span class="kc">False</span><span class="p">})</span>
|
|
<span class="c1"># test valid inputs</span>
|
|
<span class="k">for</span> <span class="nb">input</span><span class="p">,</span> <span class="n">output</span> <span class="ow">in</span> <span class="n">valid</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">required</span><span class="o">.</span><span class="n">clean</span><span class="p">(</span><span class="nb">input</span><span class="p">),</span> <span class="n">output</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">optional</span><span class="o">.</span><span class="n">clean</span><span class="p">(</span><span class="nb">input</span><span class="p">),</span> <span class="n">output</span><span class="p">)</span>
|
|
<span class="c1"># test invalid inputs</span>
|
|
<span class="k">for</span> <span class="nb">input</span><span class="p">,</span> <span class="n">errors</span> <span class="ow">in</span> <span class="n">invalid</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">assertRaises</span><span class="p">(</span><span class="n">ValidationError</span><span class="p">)</span> <span class="k">as</span> <span class="n">context_manager</span><span class="p">:</span>
|
|
<span class="n">required</span><span class="o">.</span><span class="n">clean</span><span class="p">(</span><span class="nb">input</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">context_manager</span><span class="o">.</span><span class="n">exception</span><span class="o">.</span><span class="n">messages</span><span class="p">,</span> <span class="n">errors</span><span class="p">)</span>
|
|
|
|
<span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">assertRaises</span><span class="p">(</span><span class="n">ValidationError</span><span class="p">)</span> <span class="k">as</span> <span class="n">context_manager</span><span class="p">:</span>
|
|
<span class="n">optional</span><span class="o">.</span><span class="n">clean</span><span class="p">(</span><span class="nb">input</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">context_manager</span><span class="o">.</span><span class="n">exception</span><span class="o">.</span><span class="n">messages</span><span class="p">,</span> <span class="n">errors</span><span class="p">)</span>
|
|
<span class="c1"># test required inputs</span>
|
|
<span class="n">error_required</span> <span class="o">=</span> <span class="p">[</span><span class="n">required</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">"required"</span><span class="p">]]</span>
|
|
<span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">required</span><span class="o">.</span><span class="n">empty_values</span><span class="p">:</span>
|
|
<span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">assertRaises</span><span class="p">(</span><span class="n">ValidationError</span><span class="p">)</span> <span class="k">as</span> <span class="n">context_manager</span><span class="p">:</span>
|
|
<span class="n">required</span><span class="o">.</span><span class="n">clean</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">context_manager</span><span class="o">.</span><span class="n">exception</span><span class="o">.</span><span class="n">messages</span><span class="p">,</span> <span class="n">error_required</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">optional</span><span class="o">.</span><span class="n">clean</span><span class="p">(</span><span class="n">e</span><span class="p">),</span> <span class="n">empty_value</span><span class="p">)</span>
|
|
<span class="c1"># test that max_length and min_length are always accepted</span>
|
|
<span class="k">if</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">fieldclass</span><span class="p">,</span> <span class="n">CharField</span><span class="p">):</span>
|
|
<span class="n">field_kwargs</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="s2">"min_length"</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span> <span class="s2">"max_length"</span><span class="p">:</span> <span class="mi">20</span><span class="p">})</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertIsInstance</span><span class="p">(</span><span class="n">fieldclass</span><span class="p">(</span><span class="o">*</span><span class="n">field_args</span><span class="p">,</span> <span class="o">**</span><span class="n">field_kwargs</span><span class="p">),</span> <span class="n">fieldclass</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assertHTMLEqual</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">html1</span><span class="p">,</span> <span class="n">html2</span><span class="p">,</span> <span class="n">msg</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Assert that two HTML snippets are semantically the same.</span>
|
|
<span class="sd"> Whitespace in most cases is ignored, and attribute ordering is not</span>
|
|
<span class="sd"> significant. The arguments must be valid HTML.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">dom1</span> <span class="o">=</span> <span class="n">assert_and_parse_html</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="p">,</span> <span class="n">html1</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="s2">"First argument is not valid HTML:"</span>
|
|
<span class="p">)</span>
|
|
<span class="n">dom2</span> <span class="o">=</span> <span class="n">assert_and_parse_html</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="p">,</span> <span class="n">html2</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="s2">"Second argument is not valid HTML:"</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">dom1</span> <span class="o">!=</span> <span class="n">dom2</span><span class="p">:</span>
|
|
<span class="n">standardMsg</span> <span class="o">=</span> <span class="s2">"</span><span class="si">%s</span><span class="s2"> != </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">safe_repr</span><span class="p">(</span><span class="n">dom1</span><span class="p">,</span> <span class="kc">True</span><span class="p">),</span> <span class="n">safe_repr</span><span class="p">(</span><span class="n">dom2</span><span class="p">,</span> <span class="kc">True</span><span class="p">))</span>
|
|
<span class="n">diff</span> <span class="o">=</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span> <span class="o">+</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
|
|
<span class="n">difflib</span><span class="o">.</span><span class="n">ndiff</span><span class="p">(</span>
|
|
<span class="nb">str</span><span class="p">(</span><span class="n">dom1</span><span class="p">)</span><span class="o">.</span><span class="n">splitlines</span><span class="p">(),</span>
|
|
<span class="nb">str</span><span class="p">(</span><span class="n">dom2</span><span class="p">)</span><span class="o">.</span><span class="n">splitlines</span><span class="p">(),</span>
|
|
<span class="p">)</span>
|
|
<span class="p">)</span>
|
|
<span class="n">standardMsg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_truncateMessage</span><span class="p">(</span><span class="n">standardMsg</span><span class="p">,</span> <span class="n">diff</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">fail</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_formatMessage</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">standardMsg</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assertHTMLNotEqual</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">html1</span><span class="p">,</span> <span class="n">html2</span><span class="p">,</span> <span class="n">msg</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Assert that two HTML snippets are not semantically equivalent."""</span>
|
|
<span class="n">dom1</span> <span class="o">=</span> <span class="n">assert_and_parse_html</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="p">,</span> <span class="n">html1</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="s2">"First argument is not valid HTML:"</span>
|
|
<span class="p">)</span>
|
|
<span class="n">dom2</span> <span class="o">=</span> <span class="n">assert_and_parse_html</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="p">,</span> <span class="n">html2</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="s2">"Second argument is not valid HTML:"</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">dom1</span> <span class="o">==</span> <span class="n">dom2</span><span class="p">:</span>
|
|
<span class="n">standardMsg</span> <span class="o">=</span> <span class="s2">"</span><span class="si">%s</span><span class="s2"> == </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">safe_repr</span><span class="p">(</span><span class="n">dom1</span><span class="p">,</span> <span class="kc">True</span><span class="p">),</span> <span class="n">safe_repr</span><span class="p">(</span><span class="n">dom2</span><span class="p">,</span> <span class="kc">True</span><span class="p">))</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">fail</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_formatMessage</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">standardMsg</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assertInHTML</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">needle</span><span class="p">,</span> <span class="n">haystack</span><span class="p">,</span> <span class="n">count</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="o">=</span><span class="s2">""</span><span class="p">):</span>
|
|
<span class="n">parsed_needle</span> <span class="o">=</span> <span class="n">assert_and_parse_html</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="p">,</span> <span class="n">needle</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="s2">"First argument is not valid HTML:"</span>
|
|
<span class="p">)</span>
|
|
<span class="n">parsed_haystack</span> <span class="o">=</span> <span class="n">assert_and_parse_html</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="p">,</span> <span class="n">haystack</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="s2">"Second argument is not valid HTML:"</span>
|
|
<span class="p">)</span>
|
|
<span class="n">real_count</span> <span class="o">=</span> <span class="n">parsed_haystack</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="n">parsed_needle</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">msg_prefix</span><span class="p">:</span>
|
|
<span class="n">msg_prefix</span> <span class="o">+=</span> <span class="s2">": "</span>
|
|
<span class="n">haystack_repr</span> <span class="o">=</span> <span class="n">safe_repr</span><span class="p">(</span><span class="n">haystack</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">count</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">count</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">needle</span><span class="si">!r}</span><span class="s2"> unexpectedly found in the following response</span><span class="se">\n</span><span class="s2">"</span>
|
|
<span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">haystack_repr</span><span class="si">}</span><span class="s2">"</span>
|
|
<span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">msg</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"Found </span><span class="si">{</span><span class="n">real_count</span><span class="si">}</span><span class="s2"> instances of </span><span class="si">{</span><span class="n">needle</span><span class="si">!r}</span><span class="s2"> (expected </span><span class="si">{</span><span class="n">count</span><span class="si">}</span><span class="s2">) in "</span>
|
|
<span class="sa">f</span><span class="s2">"the following response</span><span class="se">\n</span><span class="si">{</span><span class="n">haystack_repr</span><span class="si">}</span><span class="s2">"</span>
|
|
<span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">real_count</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">msg_prefix</span><span class="si">}{</span><span class="n">msg</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span>
|
|
<span class="n">real_count</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">,</span>
|
|
<span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">msg_prefix</span><span class="si">}</span><span class="s2">Couldn't find </span><span class="si">{</span><span class="n">needle</span><span class="si">!r}</span><span class="s2"> in the following response</span><span class="se">\n</span><span class="s2">"</span>
|
|
<span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">haystack_repr</span><span class="si">}</span><span class="s2">"</span>
|
|
<span class="p">),</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assertNotInHTML</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">needle</span><span class="p">,</span> <span class="n">haystack</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="o">=</span><span class="s2">""</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertInHTML</span><span class="p">(</span><span class="n">needle</span><span class="p">,</span> <span class="n">haystack</span><span class="p">,</span> <span class="n">count</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">msg_prefix</span><span class="o">=</span><span class="n">msg_prefix</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assertJSONEqual</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">raw</span><span class="p">,</span> <span class="n">expected_data</span><span class="p">,</span> <span class="n">msg</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Assert that the JSON fragments raw and expected_data are equal.</span>
|
|
<span class="sd"> Usual JSON non-significant whitespace rules apply as the heavyweight</span>
|
|
<span class="sd"> is delegated to the json library.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">data</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">raw</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="n">json</span><span class="o">.</span><span class="n">JSONDecodeError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">fail</span><span class="p">(</span><span class="s2">"First argument is not valid JSON: </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="n">raw</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expected_data</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">expected_data</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">expected_data</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">fail</span><span class="p">(</span><span class="s2">"Second argument is not valid JSON: </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="n">expected_data</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">expected_data</span><span class="p">,</span> <span class="n">msg</span><span class="o">=</span><span class="n">msg</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assertJSONNotEqual</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">raw</span><span class="p">,</span> <span class="n">expected_data</span><span class="p">,</span> <span class="n">msg</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Assert that the JSON fragments raw and expected_data are not equal.</span>
|
|
<span class="sd"> Usual JSON non-significant whitespace rules apply as the heavyweight</span>
|
|
<span class="sd"> is delegated to the json library.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">data</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">raw</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="n">json</span><span class="o">.</span><span class="n">JSONDecodeError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">fail</span><span class="p">(</span><span class="s2">"First argument is not valid JSON: </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="n">raw</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">expected_data</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">expected_data</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">expected_data</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="n">json</span><span class="o">.</span><span class="n">JSONDecodeError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">fail</span><span class="p">(</span><span class="s2">"Second argument is not valid JSON: </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="n">expected_data</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">assertNotEqual</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">expected_data</span><span class="p">,</span> <span class="n">msg</span><span class="o">=</span><span class="n">msg</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assertXMLEqual</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">xml1</span><span class="p">,</span> <span class="n">xml2</span><span class="p">,</span> <span class="n">msg</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Assert that two XML snippets are semantically the same.</span>
|
|
<span class="sd"> Whitespace in most cases is ignored and attribute ordering is not</span>
|
|
<span class="sd"> significant. The arguments must be valid XML.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">result</span> <span class="o">=</span> <span class="n">compare_xml</span><span class="p">(</span><span class="n">xml1</span><span class="p">,</span> <span class="n">xml2</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
|
<span class="n">standardMsg</span> <span class="o">=</span> <span class="s2">"First or second argument is not valid XML</span><span class="se">\n</span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="n">e</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">fail</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_formatMessage</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">standardMsg</span><span class="p">))</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="p">:</span>
|
|
<span class="n">standardMsg</span> <span class="o">=</span> <span class="s2">"</span><span class="si">%s</span><span class="s2"> != </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span>
|
|
<span class="n">safe_repr</span><span class="p">(</span><span class="n">xml1</span><span class="p">,</span> <span class="kc">True</span><span class="p">),</span>
|
|
<span class="n">safe_repr</span><span class="p">(</span><span class="n">xml2</span><span class="p">,</span> <span class="kc">True</span><span class="p">),</span>
|
|
<span class="p">)</span>
|
|
<span class="n">diff</span> <span class="o">=</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span> <span class="o">+</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
|
|
<span class="n">difflib</span><span class="o">.</span><span class="n">ndiff</span><span class="p">(</span><span class="n">xml1</span><span class="o">.</span><span class="n">splitlines</span><span class="p">(),</span> <span class="n">xml2</span><span class="o">.</span><span class="n">splitlines</span><span class="p">())</span>
|
|
<span class="p">)</span>
|
|
<span class="n">standardMsg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_truncateMessage</span><span class="p">(</span><span class="n">standardMsg</span><span class="p">,</span> <span class="n">diff</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">fail</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_formatMessage</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">standardMsg</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assertXMLNotEqual</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">xml1</span><span class="p">,</span> <span class="n">xml2</span><span class="p">,</span> <span class="n">msg</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Assert that two XML snippets are not semantically equivalent.</span>
|
|
<span class="sd"> Whitespace in most cases is ignored and attribute ordering is not</span>
|
|
<span class="sd"> significant. The arguments must be valid XML.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">result</span> <span class="o">=</span> <span class="n">compare_xml</span><span class="p">(</span><span class="n">xml1</span><span class="p">,</span> <span class="n">xml2</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
|
<span class="n">standardMsg</span> <span class="o">=</span> <span class="s2">"First or second argument is not valid XML</span><span class="se">\n</span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="n">e</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">fail</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_formatMessage</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">standardMsg</span><span class="p">))</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">result</span><span class="p">:</span>
|
|
<span class="n">standardMsg</span> <span class="o">=</span> <span class="s2">"</span><span class="si">%s</span><span class="s2"> == </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span>
|
|
<span class="n">safe_repr</span><span class="p">(</span><span class="n">xml1</span><span class="p">,</span> <span class="kc">True</span><span class="p">),</span>
|
|
<span class="n">safe_repr</span><span class="p">(</span><span class="n">xml2</span><span class="p">,</span> <span class="kc">True</span><span class="p">),</span>
|
|
<span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">fail</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_formatMessage</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">standardMsg</span><span class="p">))</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">TransactionTestCase</span><span class="p">(</span><span class="n">SimpleTestCase</span><span class="p">):</span>
|
|
<span class="c1"># Subclasses can ask for resetting of auto increment sequence before each</span>
|
|
<span class="c1"># test case</span>
|
|
<span class="n">reset_sequences</span> <span class="o">=</span> <span class="kc">False</span>
|
|
|
|
<span class="c1"># Subclasses can enable only a subset of apps for faster tests</span>
|
|
<span class="n">available_apps</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="c1"># Subclasses can define fixtures which will be automatically installed.</span>
|
|
<span class="n">fixtures</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="n">databases</span> <span class="o">=</span> <span class="p">{</span><span class="n">DEFAULT_DB_ALIAS</span><span class="p">}</span>
|
|
<span class="n">_disallowed_database_msg</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="s2">"Database </span><span class="si">%(operation)s</span><span class="s2"> to </span><span class="si">%(alias)r</span><span class="s2"> are not allowed in this test. "</span>
|
|
<span class="s2">"Add </span><span class="si">%(alias)r</span><span class="s2"> to </span><span class="si">%(test)s</span><span class="s2">.databases to ensure proper test isolation "</span>
|
|
<span class="s2">"and silence this failure."</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># If transactions aren't available, Django will serialize the database</span>
|
|
<span class="c1"># contents into a fixture during setup and flush and reload them</span>
|
|
<span class="c1"># during teardown (as flush does not restore data from migrations).</span>
|
|
<span class="c1"># This can be slow; this flag allows enabling on a per-case basis.</span>
|
|
<span class="n">serialized_rollback</span> <span class="o">=</span> <span class="kc">False</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_pre_setup</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Perform pre-test setup:</span>
|
|
<span class="sd"> * If the class has an 'available_apps' attribute, restrict the app</span>
|
|
<span class="sd"> registry to these applications, then fire the post_migrate signal --</span>
|
|
<span class="sd"> it must run with the correct set of applications for the test case.</span>
|
|
<span class="sd"> * If the class has a 'fixtures' attribute, install those fixtures.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">_pre_setup</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">available_apps</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">apps</span><span class="o">.</span><span class="n">set_available_apps</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">available_apps</span><span class="p">)</span>
|
|
<span class="n">setting_changed</span><span class="o">.</span><span class="n">send</span><span class="p">(</span>
|
|
<span class="n">sender</span><span class="o">=</span><span class="n">settings</span><span class="o">.</span><span class="n">_wrapped</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span>
|
|
<span class="n">setting</span><span class="o">=</span><span class="s2">"INSTALLED_APPS"</span><span class="p">,</span>
|
|
<span class="n">value</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">available_apps</span><span class="p">,</span>
|
|
<span class="n">enter</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">db_name</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_databases_names</span><span class="p">(</span><span class="n">include_mirrors</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="n">emit_post_migrate_signal</span><span class="p">(</span><span class="n">verbosity</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">interactive</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">db</span><span class="o">=</span><span class="n">db_name</span><span class="p">)</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_fixture_setup</span><span class="p">()</span>
|
|
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">available_apps</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">apps</span><span class="o">.</span><span class="n">unset_available_apps</span><span class="p">()</span>
|
|
<span class="n">setting_changed</span><span class="o">.</span><span class="n">send</span><span class="p">(</span>
|
|
<span class="n">sender</span><span class="o">=</span><span class="n">settings</span><span class="o">.</span><span class="n">_wrapped</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span>
|
|
<span class="n">setting</span><span class="o">=</span><span class="s2">"INSTALLED_APPS"</span><span class="p">,</span>
|
|
<span class="n">value</span><span class="o">=</span><span class="n">settings</span><span class="o">.</span><span class="n">INSTALLED_APPS</span><span class="p">,</span>
|
|
<span class="n">enter</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="k">raise</span>
|
|
<span class="c1"># Clear the queries_log so that it's less likely to overflow (a single</span>
|
|
<span class="c1"># test probably won't execute 9K queries). If queries_log overflows,</span>
|
|
<span class="c1"># then assertNumQueries() doesn't work.</span>
|
|
<span class="k">for</span> <span class="n">db_name</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_databases_names</span><span class="p">(</span><span class="n">include_mirrors</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="n">connections</span><span class="p">[</span><span class="n">db_name</span><span class="p">]</span><span class="o">.</span><span class="n">queries_log</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_databases_names</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">include_mirrors</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="c1"># Only consider allowed database aliases, including mirrors or not.</span>
|
|
<span class="k">return</span> <span class="p">[</span>
|
|
<span class="n">alias</span>
|
|
<span class="k">for</span> <span class="n">alias</span> <span class="ow">in</span> <span class="n">connections</span>
|
|
<span class="k">if</span> <span class="n">alias</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">databases</span>
|
|
<span class="ow">and</span> <span class="p">(</span>
|
|
<span class="n">include_mirrors</span>
|
|
<span class="ow">or</span> <span class="ow">not</span> <span class="n">connections</span><span class="p">[</span><span class="n">alias</span><span class="p">]</span><span class="o">.</span><span class="n">settings_dict</span><span class="p">[</span><span class="s2">"TEST"</span><span class="p">][</span><span class="s2">"MIRROR"</span><span class="p">]</span>
|
|
<span class="p">)</span>
|
|
<span class="p">]</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_reset_sequences</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">db_name</span><span class="p">):</span>
|
|
<span class="n">conn</span> <span class="o">=</span> <span class="n">connections</span><span class="p">[</span><span class="n">db_name</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">conn</span><span class="o">.</span><span class="n">features</span><span class="o">.</span><span class="n">supports_sequence_reset</span><span class="p">:</span>
|
|
<span class="n">sql_list</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">ops</span><span class="o">.</span><span class="n">sequence_reset_by_name_sql</span><span class="p">(</span>
|
|
<span class="n">no_style</span><span class="p">(),</span> <span class="n">conn</span><span class="o">.</span><span class="n">introspection</span><span class="o">.</span><span class="n">sequence_list</span><span class="p">()</span>
|
|
<span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">sql_list</span><span class="p">:</span>
|
|
<span class="k">with</span> <span class="n">transaction</span><span class="o">.</span><span class="n">atomic</span><span class="p">(</span><span class="n">using</span><span class="o">=</span><span class="n">db_name</span><span class="p">):</span>
|
|
<span class="k">with</span> <span class="n">conn</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span> <span class="k">as</span> <span class="n">cursor</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">sql</span> <span class="ow">in</span> <span class="n">sql_list</span><span class="p">:</span>
|
|
<span class="n">cursor</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">sql</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_fixture_setup</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">for</span> <span class="n">db_name</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_databases_names</span><span class="p">(</span><span class="n">include_mirrors</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="c1"># Reset sequences</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">reset_sequences</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_reset_sequences</span><span class="p">(</span><span class="n">db_name</span><span class="p">)</span>
|
|
|
|
<span class="c1"># Provide replica initial data from migrated apps, if needed.</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">serialized_rollback</span> <span class="ow">and</span> <span class="nb">hasattr</span><span class="p">(</span>
|
|
<span class="n">connections</span><span class="p">[</span><span class="n">db_name</span><span class="p">],</span> <span class="s2">"_test_serialized_contents"</span>
|
|
<span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">available_apps</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">apps</span><span class="o">.</span><span class="n">unset_available_apps</span><span class="p">()</span>
|
|
<span class="n">connections</span><span class="p">[</span><span class="n">db_name</span><span class="p">]</span><span class="o">.</span><span class="n">creation</span><span class="o">.</span><span class="n">deserialize_db_from_string</span><span class="p">(</span>
|
|
<span class="n">connections</span><span class="p">[</span><span class="n">db_name</span><span class="p">]</span><span class="o">.</span><span class="n">_test_serialized_contents</span>
|
|
<span class="p">)</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">available_apps</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">apps</span><span class="o">.</span><span class="n">set_available_apps</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">available_apps</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fixtures</span><span class="p">:</span>
|
|
<span class="n">call_command</span><span class="p">(</span><span class="s2">"loaddata"</span><span class="p">,</span> <span class="o">*</span><span class="bp">self</span><span class="o">.</span><span class="n">fixtures</span><span class="p">,</span> <span class="n">verbosity</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">database</span><span class="o">=</span><span class="n">db_name</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_should_reload_connections</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="kc">True</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_post_teardown</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Perform post-test things:</span>
|
|
<span class="sd"> * Flush the contents of the database to leave a clean slate. If the</span>
|
|
<span class="sd"> class has an 'available_apps' attribute, don't fire post_migrate.</span>
|
|
<span class="sd"> * Force-close the connection so the next test gets a clean cursor.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_fixture_teardown</span><span class="p">()</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">_post_teardown</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_should_reload_connections</span><span class="p">():</span>
|
|
<span class="c1"># Some DB cursors include SQL statements as part of cursor</span>
|
|
<span class="c1"># creation. If you have a test that does a rollback, the effect</span>
|
|
<span class="c1"># of these statements is lost, which can affect the operation of</span>
|
|
<span class="c1"># tests (e.g., losing a timezone setting causing objects to be</span>
|
|
<span class="c1"># created with the wrong time). To make sure this doesn't</span>
|
|
<span class="c1"># happen, get a clean connection at the start of every test.</span>
|
|
<span class="k">for</span> <span class="n">conn</span> <span class="ow">in</span> <span class="n">connections</span><span class="o">.</span><span class="n">all</span><span class="p">(</span><span class="n">initialized_only</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="n">conn</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
|
|
<span class="k">finally</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">available_apps</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">apps</span><span class="o">.</span><span class="n">unset_available_apps</span><span class="p">()</span>
|
|
<span class="n">setting_changed</span><span class="o">.</span><span class="n">send</span><span class="p">(</span>
|
|
<span class="n">sender</span><span class="o">=</span><span class="n">settings</span><span class="o">.</span><span class="n">_wrapped</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span>
|
|
<span class="n">setting</span><span class="o">=</span><span class="s2">"INSTALLED_APPS"</span><span class="p">,</span>
|
|
<span class="n">value</span><span class="o">=</span><span class="n">settings</span><span class="o">.</span><span class="n">INSTALLED_APPS</span><span class="p">,</span>
|
|
<span class="n">enter</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_fixture_teardown</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="c1"># Allow TRUNCATE ... CASCADE and don't emit the post_migrate signal</span>
|
|
<span class="c1"># when flushing only a subset of the apps</span>
|
|
<span class="k">for</span> <span class="n">db_name</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_databases_names</span><span class="p">(</span><span class="n">include_mirrors</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="c1"># Flush the database</span>
|
|
<span class="n">inhibit_post_migrate</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">available_apps</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
|
|
<span class="ow">or</span> <span class="p">(</span> <span class="c1"># Inhibit the post_migrate signal when using serialized</span>
|
|
<span class="c1"># rollback to avoid trying to recreate the serialized data.</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">serialized_rollback</span>
|
|
<span class="ow">and</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">connections</span><span class="p">[</span><span class="n">db_name</span><span class="p">],</span> <span class="s2">"_test_serialized_contents"</span><span class="p">)</span>
|
|
<span class="p">)</span>
|
|
<span class="p">)</span>
|
|
<span class="n">call_command</span><span class="p">(</span>
|
|
<span class="s2">"flush"</span><span class="p">,</span>
|
|
<span class="n">verbosity</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
|
|
<span class="n">interactive</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
|
|
<span class="n">database</span><span class="o">=</span><span class="n">db_name</span><span class="p">,</span>
|
|
<span class="n">reset_sequences</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
|
|
<span class="n">allow_cascade</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">available_apps</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">inhibit_post_migrate</span><span class="o">=</span><span class="n">inhibit_post_migrate</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assertQuerySetEqual</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">qs</span><span class="p">,</span> <span class="n">values</span><span class="p">,</span> <span class="n">transform</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">ordered</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">msg</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="n">values</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">values</span><span class="p">)</span>
|
|
<span class="n">items</span> <span class="o">=</span> <span class="n">qs</span>
|
|
<span class="k">if</span> <span class="n">transform</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">items</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">transform</span><span class="p">,</span> <span class="n">items</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">ordered</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">assertDictEqual</span><span class="p">(</span><span class="n">Counter</span><span class="p">(</span><span class="n">items</span><span class="p">),</span> <span class="n">Counter</span><span class="p">(</span><span class="n">values</span><span class="p">),</span> <span class="n">msg</span><span class="o">=</span><span class="n">msg</span><span class="p">)</span>
|
|
<span class="c1"># For example qs.iterator() could be passed as qs, but it does not</span>
|
|
<span class="c1"># have 'ordered' attribute.</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">values</span><span class="p">)</span> <span class="o">></span> <span class="mi">1</span> <span class="ow">and</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">qs</span><span class="p">,</span> <span class="s2">"ordered"</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">qs</span><span class="o">.</span><span class="n">ordered</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
|
|
<span class="s2">"Trying to compare non-ordered queryset against more than one "</span>
|
|
<span class="s2">"ordered value."</span>
|
|
<span class="p">)</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">items</span><span class="p">),</span> <span class="n">values</span><span class="p">,</span> <span class="n">msg</span><span class="o">=</span><span class="n">msg</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">assertNumQueries</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">num</span><span class="p">,</span> <span class="n">func</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">using</span><span class="o">=</span><span class="n">DEFAULT_DB_ALIAS</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="n">conn</span> <span class="o">=</span> <span class="n">connections</span><span class="p">[</span><span class="n">using</span><span class="p">]</span>
|
|
|
|
<span class="n">context</span> <span class="o">=</span> <span class="n">_AssertNumQueriesContext</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">num</span><span class="p">,</span> <span class="n">conn</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">func</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">context</span>
|
|
|
|
<span class="k">with</span> <span class="n">context</span><span class="p">:</span>
|
|
<span class="n">func</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">connections_support_transactions</span><span class="p">(</span><span class="n">aliases</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Return whether or not all (or specified) connections support</span>
|
|
<span class="sd"> transactions.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">conns</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="n">connections</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="n">aliases</span> <span class="ow">is</span> <span class="kc">None</span>
|
|
<span class="k">else</span> <span class="p">(</span><span class="n">connections</span><span class="p">[</span><span class="n">alias</span><span class="p">]</span> <span class="k">for</span> <span class="n">alias</span> <span class="ow">in</span> <span class="n">aliases</span><span class="p">)</span>
|
|
<span class="p">)</span>
|
|
<span class="k">return</span> <span class="nb">all</span><span class="p">(</span><span class="n">conn</span><span class="o">.</span><span class="n">features</span><span class="o">.</span><span class="n">supports_transactions</span> <span class="k">for</span> <span class="n">conn</span> <span class="ow">in</span> <span class="n">conns</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">connections_support_savepoints</span><span class="p">(</span><span class="n">aliases</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Return whether or not all (or specified) connections support savepoints.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">conns</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="n">connections</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="n">aliases</span> <span class="ow">is</span> <span class="kc">None</span>
|
|
<span class="k">else</span> <span class="p">(</span><span class="n">connections</span><span class="p">[</span><span class="n">alias</span><span class="p">]</span> <span class="k">for</span> <span class="n">alias</span> <span class="ow">in</span> <span class="n">aliases</span><span class="p">)</span>
|
|
<span class="p">)</span>
|
|
<span class="k">return</span> <span class="nb">all</span><span class="p">(</span><span class="n">conn</span><span class="o">.</span><span class="n">features</span><span class="o">.</span><span class="n">uses_savepoints</span> <span class="k">for</span> <span class="n">conn</span> <span class="ow">in</span> <span class="n">conns</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">TestData</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Descriptor to provide TestCase instance isolation for attributes assigned</span>
|
|
<span class="sd"> during the setUpTestData() phase.</span>
|
|
|
|
<span class="sd"> Allow safe alteration of objects assigned in setUpTestData() by test</span>
|
|
<span class="sd"> methods by exposing deep copies instead of the original objects.</span>
|
|
|
|
<span class="sd"> Objects are deep copied using a memo kept on the test case instance in</span>
|
|
<span class="sd"> order to maintain their original relationships.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="n">memo_attr</span> <span class="o">=</span> <span class="s2">"_testdata_memo"</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">data</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">get_memo</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">testcase</span><span class="p">):</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">memo</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">testcase</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">memo_attr</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="n">memo</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="nb">setattr</span><span class="p">(</span><span class="n">testcase</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">memo_attr</span><span class="p">,</span> <span class="n">memo</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">memo</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__get__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">owner</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">instance</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span>
|
|
<span class="n">memo</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_memo</span><span class="p">(</span><span class="n">instance</span><span class="p">)</span>
|
|
<span class="n">data</span> <span class="o">=</span> <span class="n">deepcopy</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">,</span> <span class="n">memo</span><span class="p">)</span>
|
|
<span class="nb">setattr</span><span class="p">(</span><span class="n">instance</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">data</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="s2">"<TestData: name=</span><span class="si">%r</span><span class="s2">, data=</span><span class="si">%r</span><span class="s2">>"</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">)</span>
|
|
|
|
|
|
<div class="viewcode-block" id="TestCase">
|
|
<a class="viewcode-back" href="../../../api/evennia.web.utils.tests.html#evennia.contrib.base_systems.awsstorage.tests.TestCase">[docs]</a>
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">TestCase</span><span class="p">(</span><span class="n">TransactionTestCase</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Similar to TransactionTestCase, but use `transaction.atomic()` to achieve</span>
|
|
<span class="sd"> test isolation.</span>
|
|
|
|
<span class="sd"> In most situations, TestCase should be preferred to TransactionTestCase as</span>
|
|
<span class="sd"> it allows faster execution. However, there are some situations where using</span>
|
|
<span class="sd"> TransactionTestCase might be necessary (e.g. testing some transactional</span>
|
|
<span class="sd"> behavior).</span>
|
|
|
|
<span class="sd"> On database backends with no transaction support, TestCase behaves as</span>
|
|
<span class="sd"> TransactionTestCase.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_enter_atomics</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Open atomic blocks for multiple databases."""</span>
|
|
<span class="n">atomics</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="k">for</span> <span class="n">db_name</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_databases_names</span><span class="p">():</span>
|
|
<span class="n">atomic</span> <span class="o">=</span> <span class="n">transaction</span><span class="o">.</span><span class="n">atomic</span><span class="p">(</span><span class="n">using</span><span class="o">=</span><span class="n">db_name</span><span class="p">)</span>
|
|
<span class="n">atomic</span><span class="o">.</span><span class="n">_from_testcase</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="n">atomic</span><span class="o">.</span><span class="fm">__enter__</span><span class="p">()</span>
|
|
<span class="n">atomics</span><span class="p">[</span><span class="n">db_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">atomic</span>
|
|
<span class="k">return</span> <span class="n">atomics</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_rollback_atomics</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">atomics</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Rollback atomic blocks opened by the previous method."""</span>
|
|
<span class="k">for</span> <span class="n">db_name</span> <span class="ow">in</span> <span class="nb">reversed</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">_databases_names</span><span class="p">()):</span>
|
|
<span class="n">transaction</span><span class="o">.</span><span class="n">set_rollback</span><span class="p">(</span><span class="kc">True</span><span class="p">,</span> <span class="n">using</span><span class="o">=</span><span class="n">db_name</span><span class="p">)</span>
|
|
<span class="n">atomics</span><span class="p">[</span><span class="n">db_name</span><span class="p">]</span><span class="o">.</span><span class="fm">__exit__</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_databases_support_transactions</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">connections_support_transactions</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">databases</span><span class="p">)</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_databases_support_savepoints</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">connections_support_savepoints</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">databases</span><span class="p">)</span>
|
|
|
|
<div class="viewcode-block" id="TestCase.setUpClass">
|
|
<a class="viewcode-back" href="../../../api/evennia.web.utils.tests.html#evennia.contrib.base_systems.awsstorage.tests.TestCase.setUpClass">[docs]</a>
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">setUpClass</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">setUpClass</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="p">(</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">_databases_support_transactions</span><span class="p">()</span>
|
|
<span class="ow">and</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_databases_support_savepoints</span><span class="p">()</span>
|
|
<span class="p">):</span>
|
|
<span class="k">return</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">cls_atomics</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_enter_atomics</span><span class="p">()</span>
|
|
|
|
<span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">fixtures</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">db_name</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_databases_names</span><span class="p">(</span><span class="n">include_mirrors</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">call_command</span><span class="p">(</span>
|
|
<span class="s2">"loaddata"</span><span class="p">,</span>
|
|
<span class="o">*</span><span class="bp">cls</span><span class="o">.</span><span class="n">fixtures</span><span class="p">,</span>
|
|
<span class="n">verbosity</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
|
|
<span class="n">database</span><span class="o">=</span><span class="n">db_name</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">_rollback_atomics</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">cls_atomics</span><span class="p">)</span>
|
|
<span class="k">raise</span>
|
|
<span class="n">pre_attrs</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">setUpTestData</span><span class="p">()</span>
|
|
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">_rollback_atomics</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">cls_atomics</span><span class="p">)</span>
|
|
<span class="k">raise</span>
|
|
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="k">if</span> <span class="n">value</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">pre_attrs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
|
|
<span class="nb">setattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">TestData</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">))</span></div>
|
|
|
|
|
|
<div class="viewcode-block" id="TestCase.tearDownClass">
|
|
<a class="viewcode-back" href="../../../api/evennia.web.utils.tests.html#evennia.contrib.base_systems.awsstorage.tests.TestCase.tearDownClass">[docs]</a>
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">tearDownClass</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="p">(</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">_databases_support_transactions</span><span class="p">()</span>
|
|
<span class="ow">and</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_databases_support_savepoints</span><span class="p">()</span>
|
|
<span class="p">):</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">_rollback_atomics</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">cls_atomics</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">conn</span> <span class="ow">in</span> <span class="n">connections</span><span class="o">.</span><span class="n">all</span><span class="p">(</span><span class="n">initialized_only</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
|
<span class="n">conn</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">tearDownClass</span><span class="p">()</span></div>
|
|
|
|
|
|
<div class="viewcode-block" id="TestCase.setUpTestData">
|
|
<a class="viewcode-back" href="../../../api/evennia.web.utils.tests.html#evennia.contrib.base_systems.awsstorage.tests.TestCase.setUpTestData">[docs]</a>
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">setUpTestData</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Load initial data for the TestCase."""</span>
|
|
<span class="k">pass</span></div>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_should_reload_connections</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_databases_support_transactions</span><span class="p">():</span>
|
|
<span class="k">return</span> <span class="kc">False</span>
|
|
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">_should_reload_connections</span><span class="p">()</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_fixture_setup</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_databases_support_transactions</span><span class="p">():</span>
|
|
<span class="c1"># If the backend does not support transactions, we should reload</span>
|
|
<span class="c1"># class data before each test</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">setUpTestData</span><span class="p">()</span>
|
|
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">_fixture_setup</span><span class="p">()</span>
|
|
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">reset_sequences</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"reset_sequences cannot be used on TestCase instances"</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">atomics</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_enter_atomics</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_databases_support_savepoints</span><span class="p">():</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fixtures</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">db_name</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_databases_names</span><span class="p">(</span><span class="n">include_mirrors</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="n">call_command</span><span class="p">(</span>
|
|
<span class="s2">"loaddata"</span><span class="p">,</span>
|
|
<span class="o">*</span><span class="bp">self</span><span class="o">.</span><span class="n">fixtures</span><span class="p">,</span>
|
|
<span class="o">**</span><span class="p">{</span><span class="s2">"verbosity"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">"database"</span><span class="p">:</span> <span class="n">db_name</span><span class="p">},</span>
|
|
<span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">setUpTestData</span><span class="p">()</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_fixture_teardown</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_databases_support_transactions</span><span class="p">():</span>
|
|
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">_fixture_teardown</span><span class="p">()</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">db_name</span> <span class="ow">in</span> <span class="nb">reversed</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_databases_names</span><span class="p">()):</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_should_check_constraints</span><span class="p">(</span><span class="n">connections</span><span class="p">[</span><span class="n">db_name</span><span class="p">]):</span>
|
|
<span class="n">connections</span><span class="p">[</span><span class="n">db_name</span><span class="p">]</span><span class="o">.</span><span class="n">check_constraints</span><span class="p">()</span>
|
|
<span class="k">finally</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_rollback_atomics</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">atomics</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_should_check_constraints</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">connection</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">features</span><span class="o">.</span><span class="n">can_defer_constraint_checks</span>
|
|
<span class="ow">and</span> <span class="ow">not</span> <span class="n">connection</span><span class="o">.</span><span class="n">needs_rollback</span>
|
|
<span class="ow">and</span> <span class="n">connection</span><span class="o">.</span><span class="n">is_usable</span><span class="p">()</span>
|
|
<span class="p">)</span>
|
|
|
|
<div class="viewcode-block" id="TestCase.captureOnCommitCallbacks">
|
|
<a class="viewcode-back" href="../../../api/evennia.web.utils.tests.html#evennia.contrib.base_systems.awsstorage.tests.TestCase.captureOnCommitCallbacks">[docs]</a>
|
|
<span class="nd">@classmethod</span>
|
|
<span class="nd">@contextmanager</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">captureOnCommitCallbacks</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">using</span><span class="o">=</span><span class="n">DEFAULT_DB_ALIAS</span><span class="p">,</span> <span class="n">execute</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Context manager to capture transaction.on_commit() callbacks."""</span>
|
|
<span class="n">callbacks</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">start_count</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">connections</span><span class="p">[</span><span class="n">using</span><span class="p">]</span><span class="o">.</span><span class="n">run_on_commit</span><span class="p">)</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">yield</span> <span class="n">callbacks</span>
|
|
<span class="k">finally</span><span class="p">:</span>
|
|
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
|
|
<span class="n">callback_count</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">connections</span><span class="p">[</span><span class="n">using</span><span class="p">]</span><span class="o">.</span><span class="n">run_on_commit</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">robust</span> <span class="ow">in</span> <span class="n">connections</span><span class="p">[</span><span class="n">using</span><span class="p">]</span><span class="o">.</span><span class="n">run_on_commit</span><span class="p">[</span>
|
|
<span class="n">start_count</span><span class="p">:</span>
|
|
<span class="p">]:</span>
|
|
<span class="n">callbacks</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">callback</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">execute</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">robust</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">callback</span><span class="p">()</span>
|
|
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
|
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"Error calling </span><span class="si">{</span><span class="n">callback</span><span class="o">.</span><span class="vm">__qualname__</span><span class="si">}</span><span class="s2"> in "</span>
|
|
<span class="sa">f</span><span class="s2">"on_commit() (%s)."</span><span class="p">,</span>
|
|
<span class="n">e</span><span class="p">,</span>
|
|
<span class="n">exc_info</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">callback</span><span class="p">()</span>
|
|
|
|
<span class="k">if</span> <span class="n">callback_count</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span><span class="n">connections</span><span class="p">[</span><span class="n">using</span><span class="p">]</span><span class="o">.</span><span class="n">run_on_commit</span><span class="p">):</span>
|
|
<span class="k">break</span>
|
|
<span class="n">start_count</span> <span class="o">=</span> <span class="n">callback_count</span></div>
|
|
</div>
|
|
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">CheckCondition</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="sd">"""Descriptor class for deferred condition checking."""</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">conditions</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">conditions</span> <span class="o">=</span> <span class="n">conditions</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">add_condition</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">condition</span><span class="p">,</span> <span class="n">reason</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="o">*</span><span class="bp">self</span><span class="o">.</span><span class="n">conditions</span><span class="p">,</span> <span class="p">(</span><span class="n">condition</span><span class="p">,</span> <span class="n">reason</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__get__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="bp">cls</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="c1"># Trigger access for all bases.</span>
|
|
<span class="k">if</span> <span class="nb">any</span><span class="p">(</span><span class="nb">getattr</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="s2">"__unittest_skip__"</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span> <span class="k">for</span> <span class="n">base</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__bases__</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="kc">True</span>
|
|
<span class="k">for</span> <span class="n">condition</span><span class="p">,</span> <span class="n">reason</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">conditions</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">condition</span><span class="p">():</span>
|
|
<span class="c1"># Override this descriptor's value and set the skip reason.</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">__unittest_skip__</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">__unittest_skip_why__</span> <span class="o">=</span> <span class="n">reason</span>
|
|
<span class="k">return</span> <span class="kc">True</span>
|
|
<span class="k">return</span> <span class="kc">False</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_deferredSkip</span><span class="p">(</span><span class="n">condition</span><span class="p">,</span> <span class="n">reason</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">decorator</span><span class="p">(</span><span class="n">test_func</span><span class="p">):</span>
|
|
<span class="k">nonlocal</span> <span class="n">condition</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="p">(</span>
|
|
<span class="nb">isinstance</span><span class="p">(</span><span class="n">test_func</span><span class="p">,</span> <span class="nb">type</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">test_func</span><span class="p">,</span> <span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">)</span>
|
|
<span class="p">):</span>
|
|
|
|
<span class="nd">@wraps</span><span class="p">(</span><span class="n">test_func</span><span class="p">)</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">skip_wrapper</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="p">(</span>
|
|
<span class="n">args</span>
|
|
<span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">)</span>
|
|
<span class="ow">and</span> <span class="n">connection</span><span class="o">.</span><span class="n">alias</span> <span class="ow">not</span> <span class="ow">in</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="s2">"databases"</span><span class="p">,</span> <span class="p">{})</span>
|
|
<span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
|
|
<span class="s2">"</span><span class="si">%s</span><span class="s2"> cannot be used on </span><span class="si">%s</span><span class="s2"> as </span><span class="si">%s</span><span class="s2"> doesn't allow queries "</span>
|
|
<span class="s2">"against the </span><span class="si">%r</span><span class="s2"> database."</span>
|
|
<span class="o">%</span> <span class="p">(</span>
|
|
<span class="n">name</span><span class="p">,</span>
|
|
<span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span>
|
|
<span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__qualname__</span><span class="p">,</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">alias</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">condition</span><span class="p">():</span>
|
|
<span class="k">raise</span> <span class="n">unittest</span><span class="o">.</span><span class="n">SkipTest</span><span class="p">(</span><span class="n">reason</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">test_func</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
|
|
|
<span class="n">test_item</span> <span class="o">=</span> <span class="n">skip_wrapper</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># Assume a class is decorated</span>
|
|
<span class="n">test_item</span> <span class="o">=</span> <span class="n">test_func</span>
|
|
<span class="n">databases</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">test_item</span><span class="p">,</span> <span class="s2">"databases"</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">databases</span> <span class="ow">or</span> <span class="n">connection</span><span class="o">.</span><span class="n">alias</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">databases</span><span class="p">:</span>
|
|
<span class="c1"># Defer raising to allow importing test class's module.</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">condition</span><span class="p">():</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
|
|
<span class="s2">"</span><span class="si">%s</span><span class="s2"> cannot be used on </span><span class="si">%s</span><span class="s2"> as it doesn't allow queries "</span>
|
|
<span class="s2">"against the '</span><span class="si">%s</span><span class="s2">' database."</span>
|
|
<span class="o">%</span> <span class="p">(</span>
|
|
<span class="n">name</span><span class="p">,</span>
|
|
<span class="n">test_item</span><span class="p">,</span>
|
|
<span class="n">connection</span><span class="o">.</span><span class="n">alias</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># Retrieve the possibly existing value from the class's dict to</span>
|
|
<span class="c1"># avoid triggering the descriptor.</span>
|
|
<span class="n">skip</span> <span class="o">=</span> <span class="n">test_func</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"__unittest_skip__"</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">skip</span><span class="p">,</span> <span class="n">CheckCondition</span><span class="p">):</span>
|
|
<span class="n">test_item</span><span class="o">.</span><span class="n">__unittest_skip__</span> <span class="o">=</span> <span class="n">skip</span><span class="o">.</span><span class="n">add_condition</span><span class="p">(</span><span class="n">condition</span><span class="p">,</span> <span class="n">reason</span><span class="p">)</span>
|
|
<span class="k">elif</span> <span class="n">skip</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">True</span><span class="p">:</span>
|
|
<span class="n">test_item</span><span class="o">.</span><span class="n">__unittest_skip__</span> <span class="o">=</span> <span class="n">CheckCondition</span><span class="p">((</span><span class="n">condition</span><span class="p">,</span> <span class="n">reason</span><span class="p">))</span>
|
|
<span class="k">return</span> <span class="n">test_item</span>
|
|
|
|
<span class="k">return</span> <span class="n">decorator</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">skipIfDBFeature</span><span class="p">(</span><span class="o">*</span><span class="n">features</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Skip a test if a database has at least one of the named features."""</span>
|
|
<span class="k">return</span> <span class="n">_deferredSkip</span><span class="p">(</span>
|
|
<span class="k">lambda</span><span class="p">:</span> <span class="nb">any</span><span class="p">(</span>
|
|
<span class="nb">getattr</span><span class="p">(</span><span class="n">connection</span><span class="o">.</span><span class="n">features</span><span class="p">,</span> <span class="n">feature</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span> <span class="k">for</span> <span class="n">feature</span> <span class="ow">in</span> <span class="n">features</span>
|
|
<span class="p">),</span>
|
|
<span class="s2">"Database has feature(s) </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="s2">", "</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">features</span><span class="p">),</span>
|
|
<span class="s2">"skipIfDBFeature"</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">skipUnlessDBFeature</span><span class="p">(</span><span class="o">*</span><span class="n">features</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Skip a test unless a database has all the named features."""</span>
|
|
<span class="k">return</span> <span class="n">_deferredSkip</span><span class="p">(</span>
|
|
<span class="k">lambda</span><span class="p">:</span> <span class="ow">not</span> <span class="nb">all</span><span class="p">(</span>
|
|
<span class="nb">getattr</span><span class="p">(</span><span class="n">connection</span><span class="o">.</span><span class="n">features</span><span class="p">,</span> <span class="n">feature</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span> <span class="k">for</span> <span class="n">feature</span> <span class="ow">in</span> <span class="n">features</span>
|
|
<span class="p">),</span>
|
|
<span class="s2">"Database doesn't support feature(s): </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="s2">", "</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">features</span><span class="p">),</span>
|
|
<span class="s2">"skipUnlessDBFeature"</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">skipUnlessAnyDBFeature</span><span class="p">(</span><span class="o">*</span><span class="n">features</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Skip a test unless a database has any of the named features."""</span>
|
|
<span class="k">return</span> <span class="n">_deferredSkip</span><span class="p">(</span>
|
|
<span class="k">lambda</span><span class="p">:</span> <span class="ow">not</span> <span class="nb">any</span><span class="p">(</span>
|
|
<span class="nb">getattr</span><span class="p">(</span><span class="n">connection</span><span class="o">.</span><span class="n">features</span><span class="p">,</span> <span class="n">feature</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span> <span class="k">for</span> <span class="n">feature</span> <span class="ow">in</span> <span class="n">features</span>
|
|
<span class="p">),</span>
|
|
<span class="s2">"Database doesn't support any of the feature(s): </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="s2">", "</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">features</span><span class="p">),</span>
|
|
<span class="s2">"skipUnlessAnyDBFeature"</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">QuietWSGIRequestHandler</span><span class="p">(</span><span class="n">WSGIRequestHandler</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> A WSGIRequestHandler that doesn't log to standard output any of the</span>
|
|
<span class="sd"> requests received, so as to not clutter the test result output.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">log_message</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">):</span>
|
|
<span class="k">pass</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">FSFilesHandler</span><span class="p">(</span><span class="n">WSGIHandler</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> WSGI middleware that intercepts calls to a directory, as defined by one of</span>
|
|
<span class="sd"> the *_ROOT settings, and serves those files, publishing them under *_URL.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">application</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">application</span> <span class="o">=</span> <span class="n">application</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">base_url</span> <span class="o">=</span> <span class="n">urlparse</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">get_base_url</span><span class="p">())</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_should_handle</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Check if the path should be handled. Ignore the path if:</span>
|
|
<span class="sd"> * the host is provided as part of the base_url</span>
|
|
<span class="sd"> * the request's path isn't under the media path (or equal)</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="n">path</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">base_url</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">base_url</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">file_path</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">url</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Return the relative path to the file on disk for the given URL."""</span>
|
|
<span class="n">relative_url</span> <span class="o">=</span> <span class="n">url</span><span class="o">.</span><span class="n">removeprefix</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">base_url</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
|
|
<span class="k">return</span> <span class="n">url2pathname</span><span class="p">(</span><span class="n">relative_url</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">get_response</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">django.http</span><span class="w"> </span><span class="kn">import</span> <span class="n">Http404</span>
|
|
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_should_handle</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">path</span><span class="p">):</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">serve</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="n">Http404</span><span class="p">:</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">get_response</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">serve</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
|
|
<span class="n">os_rel_path</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">file_path</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">path</span><span class="p">)</span>
|
|
<span class="n">os_rel_path</span> <span class="o">=</span> <span class="n">posixpath</span><span class="o">.</span><span class="n">normpath</span><span class="p">(</span><span class="n">unquote</span><span class="p">(</span><span class="n">os_rel_path</span><span class="p">))</span>
|
|
<span class="c1"># Emulate behavior of django.contrib.staticfiles.views.serve() when it</span>
|
|
<span class="c1"># invokes staticfiles' finders functionality.</span>
|
|
<span class="c1"># TODO: Modify if/when that internal API is refactored</span>
|
|
<span class="n">final_rel_path</span> <span class="o">=</span> <span class="n">os_rel_path</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">"</span><span class="se">\\</span><span class="s2">"</span><span class="p">,</span> <span class="s2">"/"</span><span class="p">)</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s2">"/"</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">serve</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">final_rel_path</span><span class="p">,</span> <span class="n">document_root</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">get_base_dir</span><span class="p">())</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_should_handle</span><span class="p">(</span><span class="n">get_path_info</span><span class="p">(</span><span class="n">environ</span><span class="p">)):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">application</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__call__</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">)</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_StaticFilesHandler</span><span class="p">(</span><span class="n">FSFilesHandler</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Handler for serving static files. A private class that is meant to be used</span>
|
|
<span class="sd"> solely as a convenience by LiveServerThread.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">get_base_dir</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">settings</span><span class="o">.</span><span class="n">STATIC_ROOT</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">get_base_url</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">settings</span><span class="o">.</span><span class="n">STATIC_URL</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">_MediaFilesHandler</span><span class="p">(</span><span class="n">FSFilesHandler</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Handler for serving the media files. A private class that is meant to be</span>
|
|
<span class="sd"> used solely as a convenience by LiveServerThread.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">get_base_dir</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">settings</span><span class="o">.</span><span class="n">MEDIA_ROOT</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">get_base_url</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">settings</span><span class="o">.</span><span class="n">MEDIA_URL</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">LiveServerThread</span><span class="p">(</span><span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Thread for running a live HTTP server while the tests are running."""</span>
|
|
|
|
<span class="n">server_class</span> <span class="o">=</span> <span class="n">ThreadedWSGIServer</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">static_handler</span><span class="p">,</span> <span class="n">connections_override</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">port</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">host</span> <span class="o">=</span> <span class="n">host</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">port</span> <span class="o">=</span> <span class="n">port</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">is_ready</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Event</span><span class="p">()</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">error</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">static_handler</span> <span class="o">=</span> <span class="n">static_handler</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">connections_override</span> <span class="o">=</span> <span class="n">connections_override</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Set up the live server and databases, and then loop over handling</span>
|
|
<span class="sd"> HTTP requests.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">connections_override</span><span class="p">:</span>
|
|
<span class="c1"># Override this thread's database connections with the ones</span>
|
|
<span class="c1"># provided by the main thread.</span>
|
|
<span class="k">for</span> <span class="n">alias</span><span class="p">,</span> <span class="n">conn</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">connections_override</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="n">connections</span><span class="p">[</span><span class="n">alias</span><span class="p">]</span> <span class="o">=</span> <span class="n">conn</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="c1"># Create the handler for serving static and media files</span>
|
|
<span class="n">handler</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">static_handler</span><span class="p">(</span><span class="n">_MediaFilesHandler</span><span class="p">(</span><span class="n">WSGIHandler</span><span class="p">()))</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">httpd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_create_server</span><span class="p">(</span>
|
|
<span class="n">connections_override</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">connections_override</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="c1"># If binding to port zero, assign the port allocated by the OS.</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">port</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">port</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">httpd</span><span class="o">.</span><span class="n">server_address</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">httpd</span><span class="o">.</span><span class="n">set_app</span><span class="p">(</span><span class="n">handler</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">is_ready</span><span class="o">.</span><span class="n">set</span><span class="p">()</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">httpd</span><span class="o">.</span><span class="n">serve_forever</span><span class="p">()</span>
|
|
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">error</span> <span class="o">=</span> <span class="n">e</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">is_ready</span><span class="o">.</span><span class="n">set</span><span class="p">()</span>
|
|
<span class="k">finally</span><span class="p">:</span>
|
|
<span class="n">connections</span><span class="o">.</span><span class="n">close_all</span><span class="p">()</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_create_server</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">connections_override</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">server_class</span><span class="p">(</span>
|
|
<span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">host</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">port</span><span class="p">),</span>
|
|
<span class="n">QuietWSGIRequestHandler</span><span class="p">,</span>
|
|
<span class="n">allow_reuse_address</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
|
|
<span class="n">connections_override</span><span class="o">=</span><span class="n">connections_override</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">terminate</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">"httpd"</span><span class="p">):</span>
|
|
<span class="c1"># Stop the WSGI server</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">httpd</span><span class="o">.</span><span class="n">shutdown</span><span class="p">()</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">httpd</span><span class="o">.</span><span class="n">server_close</span><span class="p">()</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">join</span><span class="p">()</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">LiveServerTestCase</span><span class="p">(</span><span class="n">TransactionTestCase</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Do basically the same as TransactionTestCase but also launch a live HTTP</span>
|
|
<span class="sd"> server in a separate thread so that the tests may use another testing</span>
|
|
<span class="sd"> framework, such as Selenium for example, instead of the built-in dummy</span>
|
|
<span class="sd"> client.</span>
|
|
<span class="sd"> It inherits from TransactionTestCase instead of TestCase because the</span>
|
|
<span class="sd"> threads don't share the same transactions (unless if using in-memory sqlite)</span>
|
|
<span class="sd"> and each thread needs to commit all their transactions so that the other</span>
|
|
<span class="sd"> thread can see the changes.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="n">host</span> <span class="o">=</span> <span class="s2">"localhost"</span>
|
|
<span class="n">port</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="n">server_thread_class</span> <span class="o">=</span> <span class="n">LiveServerThread</span>
|
|
<span class="n">static_handler</span> <span class="o">=</span> <span class="n">_StaticFilesHandler</span>
|
|
|
|
<span class="nd">@classproperty</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">live_server_url</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="s2">"http://</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">host</span><span class="p">,</span> <span class="bp">cls</span><span class="o">.</span><span class="n">server_thread</span><span class="o">.</span><span class="n">port</span><span class="p">)</span>
|
|
|
|
<span class="nd">@classproperty</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">allowed_host</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">cls</span><span class="o">.</span><span class="n">host</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_make_connections_override</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="n">connections_override</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="k">for</span> <span class="n">conn</span> <span class="ow">in</span> <span class="n">connections</span><span class="o">.</span><span class="n">all</span><span class="p">():</span>
|
|
<span class="c1"># If using in-memory sqlite databases, pass the connections to</span>
|
|
<span class="c1"># the server thread.</span>
|
|
<span class="k">if</span> <span class="n">conn</span><span class="o">.</span><span class="n">vendor</span> <span class="o">==</span> <span class="s2">"sqlite"</span> <span class="ow">and</span> <span class="n">conn</span><span class="o">.</span><span class="n">is_in_memory_db</span><span class="p">():</span>
|
|
<span class="n">connections_override</span><span class="p">[</span><span class="n">conn</span><span class="o">.</span><span class="n">alias</span><span class="p">]</span> <span class="o">=</span> <span class="n">conn</span>
|
|
<span class="k">return</span> <span class="n">connections_override</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">setUpClass</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">setUpClass</span><span class="p">()</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">enterClassContext</span><span class="p">(</span>
|
|
<span class="n">modify_settings</span><span class="p">(</span><span class="n">ALLOWED_HOSTS</span><span class="o">=</span><span class="p">{</span><span class="s2">"append"</span><span class="p">:</span> <span class="bp">cls</span><span class="o">.</span><span class="n">allowed_host</span><span class="p">})</span>
|
|
<span class="p">)</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">_start_server_thread</span><span class="p">()</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_start_server_thread</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="n">connections_override</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_make_connections_override</span><span class="p">()</span>
|
|
<span class="k">for</span> <span class="n">conn</span> <span class="ow">in</span> <span class="n">connections_override</span><span class="o">.</span><span class="n">values</span><span class="p">():</span>
|
|
<span class="c1"># Explicitly enable thread-shareability for this connection.</span>
|
|
<span class="n">conn</span><span class="o">.</span><span class="n">inc_thread_sharing</span><span class="p">()</span>
|
|
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">server_thread</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_create_server_thread</span><span class="p">(</span><span class="n">connections_override</span><span class="p">)</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">server_thread</span><span class="o">.</span><span class="n">daemon</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">server_thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">addClassCleanup</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">_terminate_thread</span><span class="p">)</span>
|
|
|
|
<span class="c1"># Wait for the live server to be ready</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">server_thread</span><span class="o">.</span><span class="n">is_ready</span><span class="o">.</span><span class="n">wait</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">server_thread</span><span class="o">.</span><span class="n">error</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="bp">cls</span><span class="o">.</span><span class="n">server_thread</span><span class="o">.</span><span class="n">error</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_create_server_thread</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">connections_override</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">cls</span><span class="o">.</span><span class="n">server_thread_class</span><span class="p">(</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">host</span><span class="p">,</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">static_handler</span><span class="p">,</span>
|
|
<span class="n">connections_override</span><span class="o">=</span><span class="n">connections_override</span><span class="p">,</span>
|
|
<span class="n">port</span><span class="o">=</span><span class="bp">cls</span><span class="o">.</span><span class="n">port</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">_terminate_thread</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="c1"># Terminate the live server's thread.</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">server_thread</span><span class="o">.</span><span class="n">terminate</span><span class="p">()</span>
|
|
<span class="c1"># Restore shared connections' non-shareability.</span>
|
|
<span class="k">for</span> <span class="n">conn</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">server_thread</span><span class="o">.</span><span class="n">connections_override</span><span class="o">.</span><span class="n">values</span><span class="p">():</span>
|
|
<span class="n">conn</span><span class="o">.</span><span class="n">dec_thread_sharing</span><span class="p">()</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">SerializeMixin</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="sd">"""</span>
|
|
<span class="sd"> Enforce serialization of TestCases that share a common resource.</span>
|
|
|
|
<span class="sd"> Define a common 'lockfile' for each set of TestCases to serialize. This</span>
|
|
<span class="sd"> file must exist on the filesystem.</span>
|
|
|
|
<span class="sd"> Place it early in the MRO in order to isolate setUpClass()/tearDownClass().</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="n">lockfile</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">__init_subclass__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="o">/</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">__init_subclass__</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">lockfile</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
|
|
<span class="s2">"</span><span class="si">{}</span><span class="s2">.lockfile isn't set. Set it to a unique value "</span>
|
|
<span class="s2">"in the base class."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="vm">__name__</span><span class="p">)</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="nd">@classmethod</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">setUpClass</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">_lockfile</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">lockfile</span><span class="p">)</span>
|
|
<span class="bp">cls</span><span class="o">.</span><span class="n">addClassCleanup</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">_lockfile</span><span class="o">.</span><span class="n">close</span><span class="p">)</span>
|
|
<span class="n">locks</span><span class="o">.</span><span class="n">lock</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">_lockfile</span><span class="p">,</span> <span class="n">locks</span><span class="o">.</span><span class="n">LOCK_EX</span><span class="p">)</span>
|
|
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">setUpClass</span><span class="p">()</span>
|
|
</pre></div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
<div class="related" role="navigation" aria-label="related navigation">
|
|
<h3>Navigation</h3>
|
|
<ul>
|
|
<li class="right" style="margin-right: 10px">
|
|
<a href="../../../genindex.html" title="General Index"
|
|
>index</a></li>
|
|
<li class="right" >
|
|
<a href="../../../py-modindex.html" title="Python Module Index"
|
|
>modules</a> |</li>
|
|
<li class="nav-item nav-item-0"><a href="../../../index.html">Evennia latest</a> »</li>
|
|
<li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> »</li>
|
|
<li class="nav-item nav-item-this"><a href="">django.test.testcases</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="footer" role="contentinfo">
|
|
© Copyright 2024, The Evennia developer community.
|
|
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.2.3.
|
|
</div>
|
|
</body>
|
|
</html> |