Some checks failed
CI / validate (pull_request) Failing after 5s
Bug 1: nexus_think.py line 318 — stray '.' between function call and if-block This is a SyntaxError. The entire consciousness loop cannot import. The Nexus Mind has been dead since this was committed. Bug 2: nexus_think.py line 445 — 'parser.add_.argument()' Another SyntaxError — extra underscore in argparse call. The CLI entrypoint crashes on startup. Bug 3: groq_worker.py — DEFAULT_MODEL = 'groq/llama3-8b-8192' The Groq API expects bare model names. The 'groq/' prefix causes a 404. Fixed to 'llama3-8b-8192'. Bug 4: server.py — clients.remove() in finally block Raises KeyError if the websocket was never added to the set. Fixed to clients.discard() (safe no-op if not present). Also added tracking for disconnected clients during broadcast. Bug 5: public/nexus/ — 3 corrupt duplicate files (28.6 KB wasted) app.js, style.css, and index.html all had identical content (same SHA). These are clearly a broken copy operation. The real files are at repo root. Tests: 6 new, 21/22 total pass. The 1 pre-existing failure is in test_portals_json_uses_expanded_registry_schema (schema mismatch, not related to this PR). Signed-off-by: gemini <gemini@hermes.local>
112 lines
4.3 KiB
Python
112 lines
4.3 KiB
Python
"""Tests for syntax and correctness fixes across the-nexus codebase.
|
|
|
|
Covers:
|
|
- nexus_think.py: no stray dots (SyntaxError), no typos in argparse
|
|
- groq_worker.py: model name has no 'groq/' prefix
|
|
- server.py: uses discard() not remove() for client cleanup
|
|
- public/nexus/: corrupt duplicate directory removed
|
|
"""
|
|
|
|
import ast
|
|
from pathlib import Path
|
|
|
|
|
|
NEXUS_ROOT = Path(__file__).resolve().parent.parent
|
|
|
|
|
|
# ── nexus_think.py syntax checks ────────────────────────────────────
|
|
|
|
def test_nexus_think_parses_without_syntax_error():
|
|
"""nexus_think.py must be valid Python.
|
|
|
|
Two SyntaxErrors existed:
|
|
1. Line 318: stray '.' between function call and if-block
|
|
2. Line 445: 'parser.add_.argument()' (extra underscore)
|
|
|
|
If either is present, the entire consciousness loop can't import.
|
|
"""
|
|
source = (NEXUS_ROOT / "nexus" / "nexus_think.py").read_text()
|
|
# ast.parse will raise SyntaxError if the file is invalid
|
|
try:
|
|
ast.parse(source, filename="nexus_think.py")
|
|
except SyntaxError as e:
|
|
raise AssertionError(
|
|
f"nexus_think.py has a SyntaxError at line {e.lineno}: {e.msg}"
|
|
) from e
|
|
|
|
|
|
def test_nexus_think_no_stray_dot():
|
|
"""There should be no line that is just a dot in nexus_think.py."""
|
|
source = (NEXUS_ROOT / "nexus" / "nexus_think.py").read_text()
|
|
for i, line in enumerate(source.splitlines(), 1):
|
|
stripped = line.strip()
|
|
if stripped == ".":
|
|
raise AssertionError(
|
|
f"nexus_think.py has a stray '.' on line {i}. "
|
|
"This causes a SyntaxError."
|
|
)
|
|
|
|
|
|
def test_nexus_think_argparse_no_typo():
|
|
"""parser.add_argument must not be written as parser.add_.argument."""
|
|
source = (NEXUS_ROOT / "nexus" / "nexus_think.py").read_text()
|
|
assert "add_.argument" not in source, (
|
|
"nexus_think.py contains 'add_.argument' — should be 'add_argument'."
|
|
)
|
|
|
|
|
|
# ── groq_worker.py model name ───────────────────────────────────────
|
|
|
|
def test_groq_default_model_has_no_prefix():
|
|
"""Groq API expects model names without router prefixes.
|
|
|
|
Sending 'groq/llama3-8b-8192' returns a 404.
|
|
The correct name is just 'llama3-8b-8192'.
|
|
"""
|
|
source = (NEXUS_ROOT / "nexus" / "groq_worker.py").read_text()
|
|
for line in source.splitlines():
|
|
stripped = line.strip()
|
|
if stripped.startswith("DEFAULT_MODEL") and "=" in stripped:
|
|
assert "groq/" not in stripped, (
|
|
f"groq_worker.py DEFAULT_MODEL contains 'groq/' prefix: {stripped}. "
|
|
"The Groq API expects bare model names like 'llama3-8b-8192'."
|
|
)
|
|
break
|
|
else:
|
|
# DEFAULT_MODEL not found — that's a different issue, not this test's concern
|
|
pass
|
|
|
|
|
|
# ── server.py client cleanup ────────────────────────────────────────
|
|
|
|
def test_server_uses_discard_not_remove():
|
|
"""server.py must use clients.discard() not clients.remove().
|
|
|
|
remove() raises KeyError if the websocket isn't in the set.
|
|
This happens if an exception occurs before clients.add() runs.
|
|
discard() is a safe no-op if the element isn't present.
|
|
"""
|
|
source = (NEXUS_ROOT / "server.py").read_text()
|
|
assert "clients.discard(" in source, (
|
|
"server.py should use clients.discard(websocket) for safe cleanup."
|
|
)
|
|
assert "clients.remove(" not in source, (
|
|
"server.py should NOT use clients.remove(websocket) — "
|
|
"raises KeyError if websocket wasn't added."
|
|
)
|
|
|
|
|
|
# ── public/nexus/ corrupt duplicate directory ────────────────────────
|
|
|
|
def test_public_nexus_duplicate_removed():
|
|
"""public/nexus/ contained 3 files with identical content (all 9544 bytes).
|
|
|
|
app.js, style.css, and index.html were all the same file — clearly a
|
|
corrupt copy operation. The canonical files are at the repo root.
|
|
"""
|
|
corrupt_dir = NEXUS_ROOT / "public" / "nexus"
|
|
assert not corrupt_dir.exists(), (
|
|
"public/nexus/ still exists. These are corrupt duplicates "
|
|
"(all 3 files have identical content). Remove this directory."
|
|
)
|