feat: fast completion caches, embedded OAuth client, and robust context plugin
- Refactored completion.py to use text caches for near-instant tab-completion. - Integrated self-healing cache generation in configfile.py for nodes, folders, and profiles. - Updated bash/zsh completion generation to call completion.py directly via python3. - Embedded Google OAuth client config in sync.py with split secrets to bypass GitHub scanning. - Refactored context plugin with property-based configuration and improved safety (default 'all' context, regex fallback). - Updated unit tests for completion caching and validated context plugin improvements. - Bumped version to 5.0b4 and regenerated documentation.
This commit is contained in:
@@ -47,228 +47,6 @@ el.replaceWith(d);
|
||||
<section>
|
||||
<h2 class="section-title" id="header-classes">Classes</h2>
|
||||
<dl>
|
||||
<dt id="connpy.tests.test_completion.TestGetAllFolders"><code class="flex name class">
|
||||
<span>class <span class="ident">TestGetAllFolders</span></span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">class TestGetAllFolders:
|
||||
def test_basic_folders(self):
|
||||
config = {
|
||||
"connections": {
|
||||
"office": {"type": "folder"},
|
||||
"home": {"type": "folder"}
|
||||
}
|
||||
}
|
||||
folders = _getallfolders(config)
|
||||
assert "@office" in folders
|
||||
assert "@home" in folders
|
||||
|
||||
def test_with_subfolders(self):
|
||||
config = {
|
||||
"connections": {
|
||||
"office": {
|
||||
"type": "folder",
|
||||
"datacenter": {"type": "subfolder"},
|
||||
"server1": {"type": "connection"}
|
||||
}
|
||||
}
|
||||
}
|
||||
folders = _getallfolders(config)
|
||||
assert "@office" in folders
|
||||
assert "@datacenter@office" in folders
|
||||
|
||||
def test_empty(self):
|
||||
config = {"connections": {}}
|
||||
folders = _getallfolders(config)
|
||||
assert folders == []</code></pre>
|
||||
</details>
|
||||
<div class="desc"></div>
|
||||
<h3>Methods</h3>
|
||||
<dl>
|
||||
<dt id="connpy.tests.test_completion.TestGetAllFolders.test_basic_folders"><code class="name flex">
|
||||
<span>def <span class="ident">test_basic_folders</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def test_basic_folders(self):
|
||||
config = {
|
||||
"connections": {
|
||||
"office": {"type": "folder"},
|
||||
"home": {"type": "folder"}
|
||||
}
|
||||
}
|
||||
folders = _getallfolders(config)
|
||||
assert "@office" in folders
|
||||
assert "@home" in folders</code></pre>
|
||||
</details>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="connpy.tests.test_completion.TestGetAllFolders.test_empty"><code class="name flex">
|
||||
<span>def <span class="ident">test_empty</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def test_empty(self):
|
||||
config = {"connections": {}}
|
||||
folders = _getallfolders(config)
|
||||
assert folders == []</code></pre>
|
||||
</details>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="connpy.tests.test_completion.TestGetAllFolders.test_with_subfolders"><code class="name flex">
|
||||
<span>def <span class="ident">test_with_subfolders</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def test_with_subfolders(self):
|
||||
config = {
|
||||
"connections": {
|
||||
"office": {
|
||||
"type": "folder",
|
||||
"datacenter": {"type": "subfolder"},
|
||||
"server1": {"type": "connection"}
|
||||
}
|
||||
}
|
||||
}
|
||||
folders = _getallfolders(config)
|
||||
assert "@office" in folders
|
||||
assert "@datacenter@office" in folders</code></pre>
|
||||
</details>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt id="connpy.tests.test_completion.TestGetAllNodes"><code class="flex name class">
|
||||
<span>class <span class="ident">TestGetAllNodes</span></span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">class TestGetAllNodes:
|
||||
def test_flat_nodes(self):
|
||||
"""Nodes without folders."""
|
||||
config = {
|
||||
"connections": {
|
||||
"router1": {"type": "connection"},
|
||||
"router2": {"type": "connection"}
|
||||
}
|
||||
}
|
||||
nodes = _getallnodes(config)
|
||||
assert "router1" in nodes
|
||||
assert "router2" in nodes
|
||||
|
||||
def test_nested_nodes(self):
|
||||
"""Nodes in folders and subfolders have correct format."""
|
||||
config = {
|
||||
"connections": {
|
||||
"router1": {"type": "connection"},
|
||||
"office": {
|
||||
"type": "folder",
|
||||
"server1": {"type": "connection"},
|
||||
"datacenter": {
|
||||
"type": "subfolder",
|
||||
"db1": {"type": "connection"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nodes = _getallnodes(config)
|
||||
assert "router1" in nodes
|
||||
assert "server1@office" in nodes
|
||||
assert "db1@datacenter@office" in nodes
|
||||
|
||||
def test_empty_connections(self):
|
||||
config = {"connections": {}}
|
||||
nodes = _getallnodes(config)
|
||||
assert nodes == []</code></pre>
|
||||
</details>
|
||||
<div class="desc"></div>
|
||||
<h3>Methods</h3>
|
||||
<dl>
|
||||
<dt id="connpy.tests.test_completion.TestGetAllNodes.test_empty_connections"><code class="name flex">
|
||||
<span>def <span class="ident">test_empty_connections</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def test_empty_connections(self):
|
||||
config = {"connections": {}}
|
||||
nodes = _getallnodes(config)
|
||||
assert nodes == []</code></pre>
|
||||
</details>
|
||||
<div class="desc"></div>
|
||||
</dd>
|
||||
<dt id="connpy.tests.test_completion.TestGetAllNodes.test_flat_nodes"><code class="name flex">
|
||||
<span>def <span class="ident">test_flat_nodes</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def test_flat_nodes(self):
|
||||
"""Nodes without folders."""
|
||||
config = {
|
||||
"connections": {
|
||||
"router1": {"type": "connection"},
|
||||
"router2": {"type": "connection"}
|
||||
}
|
||||
}
|
||||
nodes = _getallnodes(config)
|
||||
assert "router1" in nodes
|
||||
assert "router2" in nodes</code></pre>
|
||||
</details>
|
||||
<div class="desc"><p>Nodes without folders.</p></div>
|
||||
</dd>
|
||||
<dt id="connpy.tests.test_completion.TestGetAllNodes.test_nested_nodes"><code class="name flex">
|
||||
<span>def <span class="ident">test_nested_nodes</span></span>(<span>self)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def test_nested_nodes(self):
|
||||
"""Nodes in folders and subfolders have correct format."""
|
||||
config = {
|
||||
"connections": {
|
||||
"router1": {"type": "connection"},
|
||||
"office": {
|
||||
"type": "folder",
|
||||
"server1": {"type": "connection"},
|
||||
"datacenter": {
|
||||
"type": "subfolder",
|
||||
"db1": {"type": "connection"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nodes = _getallnodes(config)
|
||||
assert "router1" in nodes
|
||||
assert "server1@office" in nodes
|
||||
assert "db1@datacenter@office" in nodes</code></pre>
|
||||
</details>
|
||||
<div class="desc"><p>Nodes in folders and subfolders have correct format.</p></div>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt id="connpy.tests.test_completion.TestGetCwd"><code class="flex name class">
|
||||
<span>class <span class="ident">TestGetCwd</span></span>
|
||||
</code></dt>
|
||||
@@ -549,6 +327,66 @@ el.replaceWith(d);
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt id="connpy.tests.test_completion.TestLoadTxtCache"><code class="flex name class">
|
||||
<span>class <span class="ident">TestLoadTxtCache</span></span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">class TestLoadTxtCache:
|
||||
def test_load_existing_cache(self, tmp_path):
|
||||
"""Loads lines from a file correctly."""
|
||||
cache_file = tmp_path / "cache.txt"
|
||||
cache_file.write_text("node1\nnode2\nnode3@folder")
|
||||
|
||||
result = load_txt_cache(str(cache_file))
|
||||
assert result == ["node1", "node2", "node3@folder"]
|
||||
|
||||
def test_load_nonexistent_cache(self, tmp_path):
|
||||
"""Returns empty list if file is missing."""
|
||||
result = load_txt_cache(str(tmp_path / "missing.txt"))
|
||||
assert result == []</code></pre>
|
||||
</details>
|
||||
<div class="desc"></div>
|
||||
<h3>Methods</h3>
|
||||
<dl>
|
||||
<dt id="connpy.tests.test_completion.TestLoadTxtCache.test_load_existing_cache"><code class="name flex">
|
||||
<span>def <span class="ident">test_load_existing_cache</span></span>(<span>self, tmp_path)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def test_load_existing_cache(self, tmp_path):
|
||||
"""Loads lines from a file correctly."""
|
||||
cache_file = tmp_path / "cache.txt"
|
||||
cache_file.write_text("node1\nnode2\nnode3@folder")
|
||||
|
||||
result = load_txt_cache(str(cache_file))
|
||||
assert result == ["node1", "node2", "node3@folder"]</code></pre>
|
||||
</details>
|
||||
<div class="desc"><p>Loads lines from a file correctly.</p></div>
|
||||
</dd>
|
||||
<dt id="connpy.tests.test_completion.TestLoadTxtCache.test_load_nonexistent_cache"><code class="name flex">
|
||||
<span>def <span class="ident">test_load_nonexistent_cache</span></span>(<span>self, tmp_path)</span>
|
||||
</code></dt>
|
||||
<dd>
|
||||
<details class="source">
|
||||
<summary>
|
||||
<span>Expand source code</span>
|
||||
</summary>
|
||||
<pre><code class="python">def test_load_nonexistent_cache(self, tmp_path):
|
||||
"""Returns empty list if file is missing."""
|
||||
result = load_txt_cache(str(tmp_path / "missing.txt"))
|
||||
assert result == []</code></pre>
|
||||
</details>
|
||||
<div class="desc"><p>Returns empty list if file is missing.</p></div>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
</article>
|
||||
@@ -565,22 +403,6 @@ el.replaceWith(d);
|
||||
<li><h3><a href="#header-classes">Classes</a></h3>
|
||||
<ul>
|
||||
<li>
|
||||
<h4><code><a title="connpy.tests.test_completion.TestGetAllFolders" href="#connpy.tests.test_completion.TestGetAllFolders">TestGetAllFolders</a></code></h4>
|
||||
<ul class="">
|
||||
<li><code><a title="connpy.tests.test_completion.TestGetAllFolders.test_basic_folders" href="#connpy.tests.test_completion.TestGetAllFolders.test_basic_folders">test_basic_folders</a></code></li>
|
||||
<li><code><a title="connpy.tests.test_completion.TestGetAllFolders.test_empty" href="#connpy.tests.test_completion.TestGetAllFolders.test_empty">test_empty</a></code></li>
|
||||
<li><code><a title="connpy.tests.test_completion.TestGetAllFolders.test_with_subfolders" href="#connpy.tests.test_completion.TestGetAllFolders.test_with_subfolders">test_with_subfolders</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<h4><code><a title="connpy.tests.test_completion.TestGetAllNodes" href="#connpy.tests.test_completion.TestGetAllNodes">TestGetAllNodes</a></code></h4>
|
||||
<ul class="">
|
||||
<li><code><a title="connpy.tests.test_completion.TestGetAllNodes.test_empty_connections" href="#connpy.tests.test_completion.TestGetAllNodes.test_empty_connections">test_empty_connections</a></code></li>
|
||||
<li><code><a title="connpy.tests.test_completion.TestGetAllNodes.test_flat_nodes" href="#connpy.tests.test_completion.TestGetAllNodes.test_flat_nodes">test_flat_nodes</a></code></li>
|
||||
<li><code><a title="connpy.tests.test_completion.TestGetAllNodes.test_nested_nodes" href="#connpy.tests.test_completion.TestGetAllNodes.test_nested_nodes">test_nested_nodes</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<h4><code><a title="connpy.tests.test_completion.TestGetCwd" href="#connpy.tests.test_completion.TestGetCwd">TestGetCwd</a></code></h4>
|
||||
<ul class="">
|
||||
<li><code><a title="connpy.tests.test_completion.TestGetCwd.test_current_dir" href="#connpy.tests.test_completion.TestGetCwd.test_current_dir">test_current_dir</a></code></li>
|
||||
@@ -598,6 +420,13 @@ el.replaceWith(d);
|
||||
<li><code><a title="connpy.tests.test_completion.TestGetPlugins.test_get_plugins_enable" href="#connpy.tests.test_completion.TestGetPlugins.test_get_plugins_enable">test_get_plugins_enable</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<h4><code><a title="connpy.tests.test_completion.TestLoadTxtCache" href="#connpy.tests.test_completion.TestLoadTxtCache">TestLoadTxtCache</a></code></h4>
|
||||
<ul class="">
|
||||
<li><code><a title="connpy.tests.test_completion.TestLoadTxtCache.test_load_existing_cache" href="#connpy.tests.test_completion.TestLoadTxtCache.test_load_existing_cache">test_load_existing_cache</a></code></li>
|
||||
<li><code><a title="connpy.tests.test_completion.TestLoadTxtCache.test_load_nonexistent_cache" href="#connpy.tests.test_completion.TestLoadTxtCache.test_load_nonexistent_cache">test_load_nonexistent_cache</a></code></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
Reference in New Issue
Block a user