You've already forked HeurAMS-legacy
style: 代码格式化
This commit is contained in:
@@ -2,4 +2,4 @@
|
||||
HeurAMS Test Suite
|
||||
|
||||
Unit tests and examples for the Heuristic Assisted Memory Scheduler system.
|
||||
"""
|
||||
"""
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Test configuration and fixtures for HeurAMS tests.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import tempfile
|
||||
import os
|
||||
@@ -10,14 +11,16 @@ from pathlib import Path
|
||||
@pytest.fixture
|
||||
def temp_config_file():
|
||||
"""Create a temporary config file for testing."""
|
||||
with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f:
|
||||
f.write('''{
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f:
|
||||
f.write(
|
||||
"""{
|
||||
"algorithm": "sm2",
|
||||
"default_ease": 2.5,
|
||||
"learning_steps": [1, 10],
|
||||
"graduating_interval": 1,
|
||||
"easy_interval": 4
|
||||
}''')
|
||||
}"""
|
||||
)
|
||||
temp_path = f.name
|
||||
|
||||
yield temp_path
|
||||
@@ -31,21 +34,13 @@ def temp_config_file():
|
||||
def sample_atom_data():
|
||||
"""Sample atom data for testing."""
|
||||
return {
|
||||
"nucleon": {
|
||||
"content": "What is the capital of France?",
|
||||
"answer": "Paris"
|
||||
},
|
||||
"electron": {
|
||||
"ease": 2.5,
|
||||
"interval": 1,
|
||||
"repetitions": 0,
|
||||
"last_review": None
|
||||
},
|
||||
"nucleon": {"content": "What is the capital of France?", "answer": "Paris"},
|
||||
"electron": {"ease": 2.5, "interval": 1, "repetitions": 0, "last_review": None},
|
||||
"orbital": {
|
||||
"learning_steps": [1, 10],
|
||||
"graduating_interval": 1,
|
||||
"easy_interval": 4
|
||||
}
|
||||
"easy_interval": 4,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -60,4 +55,4 @@ This is a test document with some {{c1::cloze}} deletions.
|
||||
Here's another {{c2::cloze deletion}} for testing.
|
||||
|
||||
What is the capital of {{c3::France}}?
|
||||
"""
|
||||
"""
|
||||
|
||||
@@ -4,6 +4,7 @@ Examples and usage patterns for HeurAMS modules.
|
||||
This file demonstrates how to use the various HeurAMS components
|
||||
in common scenarios and workflows.
|
||||
"""
|
||||
|
||||
import json
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
@@ -28,12 +29,9 @@ class BasicUsageExamples:
|
||||
print("=== Creating Basic Atom ===")
|
||||
|
||||
# Create the components
|
||||
nucleon = Nucleon(
|
||||
content="What is the capital of France?",
|
||||
answer="Paris"
|
||||
)
|
||||
nucleon = Nucleon(content="What is the capital of France?", answer="Paris")
|
||||
electron = Electron() # Uses default values
|
||||
orbital = Orbital() # Uses default values
|
||||
orbital = Orbital() # Uses default values
|
||||
|
||||
# Combine into an Atom
|
||||
atom = Atom(nucleon=nucleon, electron=electron, orbital=orbital)
|
||||
@@ -55,7 +53,7 @@ class BasicUsageExamples:
|
||||
|
||||
nucleon = Nucleon(
|
||||
content="The {{c1::capital}} of {{c2::France}} is {{c3::Paris}}.",
|
||||
answer="capital, France, Paris"
|
||||
answer="capital, France, Paris",
|
||||
)
|
||||
electron = Electron()
|
||||
orbital = Orbital()
|
||||
@@ -126,7 +124,7 @@ class AlgorithmExamples:
|
||||
|
||||
print("\nAfter review (quality 1 - failed):")
|
||||
print(f" Repetitions: {new_electron.repetitions}") # Should reset to 0
|
||||
print(f" Interval: {new_electron.interval} days") # Should reset to 1
|
||||
print(f" Interval: {new_electron.interval} days") # Should reset to 1
|
||||
|
||||
return new_electron
|
||||
|
||||
@@ -145,20 +143,17 @@ class ReactorExamples:
|
||||
atom = Atom("test_atom")
|
||||
|
||||
# Create nucleon with content
|
||||
nucleon = Nucleon("nucleon_id", {
|
||||
"content": "What is the capital of Germany?",
|
||||
"answer": "Berlin"
|
||||
})
|
||||
nucleon = Nucleon(
|
||||
"nucleon_id",
|
||||
{"content": "What is the capital of Germany?", "answer": "Berlin"},
|
||||
)
|
||||
|
||||
# Create electron with algorithm data
|
||||
electron = Electron("electron_id")
|
||||
|
||||
# Create orbital configuration
|
||||
orbital = Orbital(
|
||||
quick_view=[["cloze", 1]],
|
||||
recognition=[],
|
||||
final_review=[],
|
||||
puzzle_config={}
|
||||
quick_view=[["cloze", 1]], recognition=[], final_review=[], puzzle_config={}
|
||||
)
|
||||
|
||||
# Link components to atom
|
||||
@@ -219,4 +214,4 @@ def run_all_examples():
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run_all_examples()
|
||||
run_all_examples()
|
||||
|
||||
@@ -3,6 +3,7 @@ Test runner script for HeurAMS.
|
||||
|
||||
This script runs all unit tests and provides a summary report.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import pytest
|
||||
import os
|
||||
@@ -22,10 +23,10 @@ def run_tests():
|
||||
|
||||
# Run tests with verbose output
|
||||
test_args = [
|
||||
"-v", # Verbose output
|
||||
"--tb=short", # Short traceback format
|
||||
"-v", # Verbose output
|
||||
"--tb=short", # Short traceback format
|
||||
"--color=yes", # Color output
|
||||
"tests/" # Test directory
|
||||
"tests/", # Test directory
|
||||
]
|
||||
|
||||
print(f"Running tests from: {os.path.abspath('tests')}")
|
||||
@@ -59,8 +60,8 @@ def run_specific_test(test_file=None, test_class=None, test_method=None):
|
||||
sys.path.insert(0, src_dir)
|
||||
|
||||
test_args = [
|
||||
"-v", # Verbose output
|
||||
"--tb=short", # Short traceback format
|
||||
"-v", # Verbose output
|
||||
"--tb=short", # Short traceback format
|
||||
"--color=yes", # Color output
|
||||
]
|
||||
|
||||
@@ -92,6 +93,7 @@ def run_examples():
|
||||
|
||||
try:
|
||||
from tests.examples import run_all_examples
|
||||
|
||||
run_all_examples()
|
||||
return 0
|
||||
except Exception as e:
|
||||
@@ -103,31 +105,21 @@ if __name__ == "__main__":
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description="HeurAMS Test Runner")
|
||||
parser.add_argument("--all", action="store_true", help="Run all tests (default)")
|
||||
parser.add_argument(
|
||||
"--all",
|
||||
action="store_true",
|
||||
help="Run all tests (default)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--file",
|
||||
type=str,
|
||||
help="Run specific test file (e.g., test_particles.py)"
|
||||
"--file", type=str, help="Run specific test file (e.g., test_particles.py)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--class",
|
||||
dest="test_class",
|
||||
type=str,
|
||||
help="Run specific test class (requires --file)"
|
||||
help="Run specific test class (requires --file)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--method",
|
||||
type=str,
|
||||
help="Run specific test method (requires --class)"
|
||||
"--method", type=str, help="Run specific test method (requires --class)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--examples",
|
||||
action="store_true",
|
||||
help="Run examples instead of tests"
|
||||
"--examples", action="store_true", help="Run examples instead of tests"
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
@@ -136,11 +128,9 @@ if __name__ == "__main__":
|
||||
exit_code = run_examples()
|
||||
elif args.file:
|
||||
exit_code = run_specific_test(
|
||||
test_file=args.file,
|
||||
test_class=args.test_class,
|
||||
test_method=args.method
|
||||
test_file=args.file, test_class=args.test_class, test_method=args.method
|
||||
)
|
||||
else:
|
||||
exit_code = run_tests()
|
||||
|
||||
sys.exit(exit_code)
|
||||
sys.exit(exit_code)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Unit tests for algorithm modules: BaseAlgorithm, SM2Algorithm
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from datetime import datetime, timezone
|
||||
|
||||
@@ -203,4 +204,4 @@ class TestSM2Algorithm:
|
||||
|
||||
# Test with None orbital
|
||||
with pytest.raises(TypeError):
|
||||
algorithm.process_review(electron, None, 3)
|
||||
algorithm.process_review(electron, None, 3)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Unit tests for particle modules: Atom, Electron, Nucleon, Orbital, Probe, Loader
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import json
|
||||
from pathlib import Path
|
||||
@@ -10,6 +11,7 @@ from src.heurams.kernel.particles.atom import Atom
|
||||
from src.heurams.kernel.particles.electron import Electron
|
||||
from src.heurams.kernel.particles.nucleon import Nucleon
|
||||
from src.heurams.kernel.particles.orbital import Orbital
|
||||
|
||||
# Probe module doesn't have a Probe class, only functions
|
||||
# Loader module doesn't have a Loader class, only functions
|
||||
|
||||
@@ -32,21 +34,18 @@ class TestAtom:
|
||||
def test_atom_from_dict(self):
|
||||
"""Test creating Atom from dictionary."""
|
||||
data = {
|
||||
"nucleon": {
|
||||
"content": "What is 2+2?",
|
||||
"answer": "4"
|
||||
},
|
||||
"nucleon": {"content": "What is 2+2?", "answer": "4"},
|
||||
"electron": {
|
||||
"ease": 2.5,
|
||||
"interval": 1,
|
||||
"repetitions": 0,
|
||||
"last_review": None
|
||||
"last_review": None,
|
||||
},
|
||||
"orbital": {
|
||||
"learning_steps": [1, 10],
|
||||
"graduating_interval": 1,
|
||||
"easy_interval": 4
|
||||
}
|
||||
"easy_interval": 4,
|
||||
},
|
||||
}
|
||||
|
||||
atom = Atom.from_dict(data)
|
||||
@@ -87,12 +86,7 @@ class TestElectron:
|
||||
def test_electron_custom_values(self):
|
||||
"""Test Electron with custom values."""
|
||||
test_time = datetime.now(timezone.utc)
|
||||
electron = Electron(
|
||||
ease=3.0,
|
||||
interval=10,
|
||||
repetitions=5,
|
||||
last_review=test_time
|
||||
)
|
||||
electron = Electron(ease=3.0, interval=10, repetitions=5, last_review=test_time)
|
||||
|
||||
assert electron.ease == 3.0
|
||||
assert electron.interval == 10
|
||||
@@ -144,10 +138,7 @@ class TestNucleon:
|
||||
|
||||
def test_nucleon_from_dict(self):
|
||||
"""Test creating Nucleon from dictionary."""
|
||||
data = {
|
||||
"content": "What is Python?",
|
||||
"answer": "A programming language"
|
||||
}
|
||||
data = {"content": "What is Python?", "answer": "A programming language"}
|
||||
|
||||
nucleon = Nucleon.from_dict(data)
|
||||
|
||||
@@ -178,9 +169,7 @@ class TestOrbital:
|
||||
def test_orbital_custom_values(self):
|
||||
"""Test Orbital with custom values."""
|
||||
orbital = Orbital(
|
||||
learning_steps=[2, 15],
|
||||
graduating_interval=2,
|
||||
easy_interval=6
|
||||
learning_steps=[2, 15], graduating_interval=2, easy_interval=6
|
||||
)
|
||||
|
||||
assert orbital.learning_steps == [2, 15]
|
||||
@@ -189,11 +178,7 @@ class TestOrbital:
|
||||
|
||||
def test_orbital_from_dict(self):
|
||||
"""Test creating Orbital from dictionary."""
|
||||
data = {
|
||||
"learning_steps": [3, 20],
|
||||
"graduating_interval": 3,
|
||||
"easy_interval": 8
|
||||
}
|
||||
data = {"learning_steps": [3, 20], "graduating_interval": 3, "easy_interval": 8}
|
||||
|
||||
orbital = Orbital.from_dict(data)
|
||||
|
||||
@@ -215,4 +200,4 @@ class TestOrbital:
|
||||
# TestProbe class removed - probe module only has functions, not a class
|
||||
|
||||
|
||||
# TestLoader class removed - loader module only has functions, not a class
|
||||
# TestLoader class removed - loader module only has functions, not a class
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Unit tests for puzzle modules: BasePuzzle, ClozePuzzle, MCQPuzzle
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import re
|
||||
|
||||
@@ -20,4 +21,4 @@ class TestBasePuzzle:
|
||||
pass
|
||||
|
||||
|
||||
# ClozePuzzle and MCQPuzzle tests skipped due to import issues
|
||||
# ClozePuzzle and MCQPuzzle tests skipped due to import issues
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Unit tests for reactor modules: Phaser, Procession, Fission, States
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from datetime import datetime, timezone
|
||||
from enum import Enum
|
||||
@@ -298,8 +299,7 @@ class TestFission:
|
||||
"""Test generating learning puzzle with cloze content."""
|
||||
fission = Fission()
|
||||
nucleon = Nucleon(
|
||||
content="The capital of {{c1::France}} is Paris.",
|
||||
answer="France"
|
||||
content="The capital of {{c1::France}} is Paris.", answer="France"
|
||||
)
|
||||
electron = Electron()
|
||||
orbital = Orbital()
|
||||
@@ -316,10 +316,7 @@ class TestFission:
|
||||
def test_fission_generate_learning_puzzle_mcq(self):
|
||||
"""Test generating learning puzzle with MCQ content."""
|
||||
fission = Fission()
|
||||
nucleon = Nucleon(
|
||||
content="What is the capital of France?",
|
||||
answer="Paris"
|
||||
)
|
||||
nucleon = Nucleon(content="What is the capital of France?", answer="Paris")
|
||||
electron = Electron()
|
||||
orbital = Orbital()
|
||||
atom = Atom(nucleon=nucleon, electron=electron, orbital=orbital)
|
||||
@@ -336,10 +333,7 @@ class TestFission:
|
||||
def test_fission_generate_review_puzzle(self):
|
||||
"""Test generating review puzzle."""
|
||||
fission = Fission()
|
||||
nucleon = Nucleon(
|
||||
content="What is the capital of France?",
|
||||
answer="Paris"
|
||||
)
|
||||
nucleon = Nucleon(content="What is the capital of France?", answer="Paris")
|
||||
electron = Electron(interval=10, repetitions=5) # In review phase
|
||||
orbital = Orbital()
|
||||
atom = Atom(nucleon=nucleon, electron=electron, orbital=orbital)
|
||||
@@ -411,4 +405,4 @@ class TestFission:
|
||||
|
||||
# Test generate_review_puzzle without initialization
|
||||
with pytest.raises(RuntimeError):
|
||||
fission.generate_review_puzzle()
|
||||
fission.generate_review_puzzle()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Unit tests for service modules: Config, Hasher, Timer, Version, AudioService, TTSService
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import json
|
||||
import tempfile
|
||||
@@ -170,4 +171,4 @@ class TestTTSService:
|
||||
|
||||
# Test speak with empty string
|
||||
with pytest.raises(ValueError):
|
||||
tts_service.speak("")
|
||||
tts_service.speak("")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Working unit tests for algorithm modules based on actual module structure.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
from src.heurams.kernel.algorithms.sm2 import SM2Algorithm
|
||||
@@ -29,12 +30,7 @@ class TestSM2Algorithm:
|
||||
|
||||
def test_sm2_is_due(self):
|
||||
"""Test SM2Algorithm is_due method."""
|
||||
algodata = {
|
||||
"SM-2": {
|
||||
"next_date": 0, # Past date
|
||||
"is_activated": 1
|
||||
}
|
||||
}
|
||||
algodata = {"SM-2": {"next_date": 0, "is_activated": 1}} # Past date
|
||||
|
||||
result = SM2Algorithm.is_due(algodata)
|
||||
|
||||
@@ -42,13 +38,7 @@ class TestSM2Algorithm:
|
||||
|
||||
def test_sm2_rate(self):
|
||||
"""Test SM2Algorithm rate method."""
|
||||
algodata = {
|
||||
"SM-2": {
|
||||
"efactor": 2.5,
|
||||
"rept": 5,
|
||||
"interval": 10
|
||||
}
|
||||
}
|
||||
algodata = {"SM-2": {"efactor": 2.5, "rept": 5, "interval": 10}}
|
||||
|
||||
result = SM2Algorithm.rate(algodata)
|
||||
|
||||
@@ -56,11 +46,7 @@ class TestSM2Algorithm:
|
||||
|
||||
def test_sm2_nextdate(self):
|
||||
"""Test SM2Algorithm nextdate method."""
|
||||
algodata = {
|
||||
"SM-2": {
|
||||
"next_date": 100
|
||||
}
|
||||
}
|
||||
algodata = {"SM-2": {"next_date": 100}}
|
||||
|
||||
result = SM2Algorithm.nextdate(algodata)
|
||||
|
||||
@@ -75,7 +61,7 @@ class TestSM2Algorithm:
|
||||
"real_rept": 0,
|
||||
"interval": 1,
|
||||
"is_activated": 1,
|
||||
"last_modify": 0
|
||||
"last_modify": 0,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,4 +71,4 @@ class TestSM2Algorithm:
|
||||
# Verify that algodata was modified
|
||||
assert "efactor" in algodata["SM-2"]
|
||||
assert "rept" in algodata["SM-2"]
|
||||
assert "interval" in algodata["SM-2"]
|
||||
assert "interval" in algodata["SM-2"]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Working unit tests for particle modules based on actual module structure.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
from src.heurams.kernel.particles.atom import Atom
|
||||
@@ -14,10 +15,7 @@ class TestNucleon:
|
||||
|
||||
def test_nucleon_creation(self):
|
||||
"""Test basic Nucleon creation."""
|
||||
payload = {
|
||||
"content": "Test content",
|
||||
"answer": "Test answer"
|
||||
}
|
||||
payload = {"content": "Test content", "answer": "Test answer"}
|
||||
nucleon = Nucleon("test_id", payload)
|
||||
|
||||
assert nucleon.ident == "test_id"
|
||||
@@ -123,7 +121,10 @@ class TestOrbital:
|
||||
quick_view=[["cloze", 1], ["mcq", 0.5]],
|
||||
recognition=[["recognition", 1]],
|
||||
final_review=[["cloze", 0.7], ["mcq", 0.7]],
|
||||
puzzle_config={"cloze": {"from": "content"}, "mcq": {"from": "keyword_note"}}
|
||||
puzzle_config={
|
||||
"cloze": {"from": "content"},
|
||||
"mcq": {"from": "keyword_note"},
|
||||
},
|
||||
)
|
||||
|
||||
assert isinstance(orbital, dict)
|
||||
@@ -138,7 +139,7 @@ class TestOrbital:
|
||||
quick_view=[["cloze", 1], ["mcq", 0.5]],
|
||||
recognition=[],
|
||||
final_review=[],
|
||||
puzzle_config={}
|
||||
puzzle_config={},
|
||||
)
|
||||
|
||||
assert len(orbital["quick_view"]) == 2
|
||||
@@ -191,4 +192,4 @@ class TestAtom:
|
||||
assert isinstance(placeholder, tuple)
|
||||
assert len(placeholder) == 3
|
||||
assert isinstance(placeholder[0], Electron)
|
||||
assert isinstance(placeholder[1], Nucleon)
|
||||
assert isinstance(placeholder[1], Nucleon)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Working unit tests for service modules based on actual module structure.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
# Version import commented out - actual module only has variables
|
||||
@@ -86,4 +87,4 @@ class TestTTSService:
|
||||
|
||||
# Test speak with empty string
|
||||
with pytest.raises(ValueError):
|
||||
tts_service.speak("")
|
||||
tts_service.speak("")
|
||||
|
||||
Reference in New Issue
Block a user