Skip to content

Commit 0908471

Browse files
committed
Improve CSV loader tests
1 parent cf592e2 commit 0908471

2 files changed

Lines changed: 94 additions & 108 deletions

File tree

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
11
fact_text,name,start_time,end_time,static
22
Viewed(Zach),seen-fact-zach,0,3,False
3-
Viewed(Justin),seen-fact-justin,0,3,False
4-
Viewed(Michelle),seen-fact-michelle,1,3,False
5-
Viewed(Amy),seen-fact-amy,2,3,False
3+
Viewed(Justin),seen-fact-justin,0,3,true
4+
Viewed(Michelle),seen-fact-michelle,1,3,FALSE
5+
Viewed(Amy),seen-fact-amy,2,3,0
66
"HaveAccess(Zach,TextMessage)",access-zach,0,5,True
7-
"HaveAccess(Justin,TextMessage)",access-justin,0,5,True
8-
"HaveAccess(Michelle,TextMessage)",access-michelle,0,5,True
9-
"HaveAccess(Amy,TextMessage)",access-amy,0,5,True
7+
"HaveAccess(Justin,TextMessage)",access-justin,0,5,1
8+
"HaveAccess(Michelle,TextMessage)",access-michelle,0,5,yes
9+
"HaveAccess(Amy,TextMessage)",access-amy,0,5,no
10+
"Processed(Node1):[0.5,0.8]",interval-node,0,10,False
11+
"Knows(Person1,Person2):[0.7,0.9]",interval-edge,0,10,True
12+
Viewed(Valid),valid-fact,0,3,False
13+
,empty-fact-text,0,3,False
14+
InvalidSyntax,bad-syntax,0,3,False
15+
"Viewed(OutOfRange):[2.5,3.0]",out-of-range,0,3,False
16+
Viewed(BadStartTime),bad-start,abc,5,False
17+
Viewed(BadEndTime),bad-end,0,xyz,False
18+
Viewed(BadStaticValue),bad-static,0,5,invalid
19+
Viewed(EmptyOptionals),,,,

tests/api_tests/test_pyreason_file_loading.py

Lines changed: 78 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -858,21 +858,58 @@ def setup_method(self):
858858
pr.reset()
859859
pr.reset_settings()
860860

861-
def test_add_fact_in_bulk_with_header(self):
862-
"""Test loading facts from CSV with header row."""
863-
csv_content = """fact_text,name,start_time,end_time,static
864-
Viewed(Zach),seen-fact-zach,0,3,False
865-
Viewed(Justin),seen-fact-justin,0,3,False
866-
"HaveAccess(Amy,TextMessage)",access-fact,0,5,True"""
861+
def test_add_fact_in_bulk_comprehensive(self):
862+
"""Test loading facts from CSV with various valid and invalid scenarios.
863+
864+
This test uses example_facts.csv which contains:
865+
- Valid node facts with various boolean formats
866+
- Valid edge facts with various boolean formats
867+
- Node and edge facts with interval bounds
868+
- Empty fact_text (should warn)
869+
- Invalid syntax (should warn)
870+
- Out of range intervals (should warn)
871+
- Invalid start_time (should warn)
872+
- Invalid end_time (should warn)
873+
- Invalid static value (should warn)
874+
- Empty optional fields
875+
"""
876+
csv_path = 'pyreason/tests/api_tests/test_files/example_facts.csv'
877+
878+
# Expect warnings for rows with invalid data:
879+
# - Row with empty fact_text
880+
# - Row with invalid syntax (missing parentheses)
881+
# - Row with out-of-range interval values
882+
# - Row with invalid start_time
883+
# - Row with invalid end_time
884+
# - Row with invalid static value
885+
with pytest.warns(UserWarning) as warning_list:
886+
pr.add_fact_in_bulk(csv_path)
867887

868-
with tempfile.NamedTemporaryFile(mode='w', suffix='.csv', delete=False) as tmp:
869-
tmp.write(csv_content)
870-
tmp_path = tmp.name
888+
# Verify that we got warnings (at least 6 from the invalid rows)
889+
assert len(warning_list) >= 6, f"Expected at least 6 warnings, got {len(warning_list)}"
871890

872-
try:
873-
pr.add_fact_in_bulk(tmp_path)
874-
finally:
875-
os.unlink(tmp_path)
891+
# Check that specific warning messages appear
892+
warning_messages = [str(w.message) for w in warning_list]
893+
894+
# Verify warning for empty fact_text
895+
assert any("Missing required 'fact_text'" in msg for msg in warning_messages), \
896+
"Expected warning about missing fact_text"
897+
898+
# Verify warning for invalid syntax
899+
assert any("Failed to parse fact" in msg and "bad-syntax" in msg for msg in warning_messages), \
900+
"Expected warning about invalid syntax"
901+
902+
# Verify warning for invalid start_time
903+
assert any("Invalid start_time" in msg for msg in warning_messages), \
904+
"Expected warning about invalid start_time"
905+
906+
# Verify warning for invalid end_time
907+
assert any("Invalid end_time" in msg for msg in warning_messages), \
908+
"Expected warning about invalid end_time"
909+
910+
# Verify warning for invalid static value
911+
assert any("Invalid static value" in msg for msg in warning_messages), \
912+
"Expected warning about invalid static value"
876913

877914
def test_add_fact_in_bulk_without_header(self):
878915
"""Test loading facts from CSV without header row."""
@@ -920,8 +957,8 @@ def test_add_fact_in_bulk_empty_optional_fields(self):
920957
finally:
921958
os.unlink(tmp_path)
922959

923-
def test_add_fact_in_bulk_with_invalid_facts(self):
924-
"""Test that invalid facts show warnings but don't crash."""
960+
def test_add_fact_in_bulk_with_invalid_facts_warnings(self):
961+
"""Test that invalid facts produce specific warnings but don't crash."""
925962
csv_content = """fact_text,name,start_time,end_time,static
926963
Viewed(Valid),valid-fact,0,3,False
927964
,empty-fact-text,0,3,False
@@ -933,8 +970,18 @@ def test_add_fact_in_bulk_with_invalid_facts(self):
933970
tmp_path = tmp.name
934971

935972
try:
936-
# Should not raise exception, only warnings
937-
pr.add_fact_in_bulk(tmp_path)
973+
# Should produce warnings for the 3 invalid rows
974+
with pytest.warns(UserWarning) as warning_list:
975+
pr.add_fact_in_bulk(tmp_path)
976+
977+
# Verify we got at least 3 warnings (one for each invalid row)
978+
assert len(warning_list) >= 3, f"Expected at least 3 warnings, got {len(warning_list)}"
979+
980+
warning_messages = [str(w.message) for w in warning_list]
981+
982+
# Verify specific warnings appear
983+
assert any("Missing required 'fact_text'" in msg for msg in warning_messages)
984+
assert any("Failed to parse fact" in msg for msg in warning_messages)
938985
finally:
939986
os.unlink(tmp_path)
940987

@@ -956,77 +1003,9 @@ def test_add_fact_in_bulk_empty_file(self):
9561003
finally:
9571004
os.unlink(tmp_path)
9581005

959-
def test_add_fact_in_bulk_node_facts(self):
960-
"""Test loading node facts (no commas in components)."""
961-
csv_content = """fact_text,name,start_time,end_time,static
962-
Viewed(Node1),fact1,0,5,False
963-
Viewed(Node2),fact2,1,5,True
964-
"Processed(Node3):[0.5,0.8]",fact3,0,10,False"""
965-
966-
with tempfile.NamedTemporaryFile(mode='w', suffix='.csv', delete=False) as tmp:
967-
tmp.write(csv_content)
968-
tmp_path = tmp.name
969-
970-
try:
971-
pr.add_fact_in_bulk(tmp_path)
972-
finally:
973-
os.unlink(tmp_path)
974-
975-
def test_add_fact_in_bulk_edge_facts(self):
976-
"""Test loading edge facts (with commas, properly quoted)."""
977-
csv_content = """fact_text,name,start_time,end_time,static
978-
"Connected(A,B)",edge1,0,5,False
979-
"Related(X,Y):True",edge2,1,5,True
980-
"Knows(Person1,Person2):[0.7,0.9]",edge3,0,10,False"""
981-
982-
with tempfile.NamedTemporaryFile(mode='w', suffix='.csv', delete=False) as tmp:
983-
tmp.write(csv_content)
984-
tmp_path = tmp.name
985-
986-
try:
987-
pr.add_fact_in_bulk(tmp_path)
988-
finally:
989-
os.unlink(tmp_path)
990-
991-
def test_add_fact_in_bulk_mixed_fact_types(self):
992-
"""Test loading both node and edge facts in same file."""
993-
csv_content = """fact_text,name,start_time,end_time,static
994-
Viewed(Alice),node-fact,0,3,False
995-
"Connected(Alice,Bob)",edge-fact,0,3,False
996-
"Processed(Charlie):[0.5,0.8]",node-interval,1,5,True
997-
"Knows(X,Y):[0.3,0.7]",edge-interval,2,5,False"""
998-
999-
with tempfile.NamedTemporaryFile(mode='w', suffix='.csv', delete=False) as tmp:
1000-
tmp.write(csv_content)
1001-
tmp_path = tmp.name
1002-
1003-
try:
1004-
pr.add_fact_in_bulk(tmp_path)
1005-
finally:
1006-
os.unlink(tmp_path)
1007-
1008-
def test_add_fact_in_bulk_various_static_values(self):
1009-
"""Test loading facts with various static value formats."""
1010-
csv_content = """fact_text,name,start_time,end_time,static
1011-
Viewed(A),fact1,0,5,True
1012-
Viewed(B),fact2,0,5,true
1013-
Viewed(C),fact3,0,5,FALSE
1014-
Viewed(D),fact4,0,5,0
1015-
Viewed(E),fact5,0,5,1
1016-
Viewed(F),fact6,0,5,yes
1017-
Viewed(G),fact7,0,5,no"""
1018-
1019-
with tempfile.NamedTemporaryFile(mode='w', suffix='.csv', delete=False) as tmp:
1020-
tmp.write(csv_content)
1021-
tmp_path = tmp.name
1022-
1023-
try:
1024-
pr.add_fact_in_bulk(tmp_path)
1025-
finally:
1026-
os.unlink(tmp_path)
10271006

10281007
def test_add_fact_in_bulk_invalid_start_end_times(self):
1029-
"""Test loading facts with invalid start/end time values."""
1008+
"""Test loading facts with invalid start/end time values produce warnings."""
10301009
csv_content = """fact_text,name,start_time,end_time,static
10311010
Viewed(A),fact1,abc,5,False
10321011
Viewed(B),fact2,0,xyz,False"""
@@ -1037,7 +1016,19 @@ def test_add_fact_in_bulk_invalid_start_end_times(self):
10371016

10381017
try:
10391018
# Should load facts with warnings about invalid times (using defaults)
1040-
pr.add_fact_in_bulk(tmp_path)
1019+
with pytest.warns(UserWarning) as warning_list:
1020+
pr.add_fact_in_bulk(tmp_path)
1021+
1022+
# Verify we got warnings for both invalid time values
1023+
assert len(warning_list) >= 2, f"Expected at least 2 warnings, got {len(warning_list)}"
1024+
1025+
warning_messages = [str(w.message) for w in warning_list]
1026+
1027+
# Verify specific warnings appear
1028+
assert any("Invalid start_time" in msg for msg in warning_messages), \
1029+
"Expected warning about invalid start_time"
1030+
assert any("Invalid end_time" in msg for msg in warning_messages), \
1031+
"Expected warning about invalid end_time"
10411032
finally:
10421033
os.unlink(tmp_path)
10431034

@@ -1061,21 +1052,6 @@ def test_add_fact_in_bulk_multiple_calls(self):
10611052
os.unlink(tmp1_path)
10621053
os.unlink(tmp2_path)
10631054

1064-
def test_add_fact_in_bulk_example_file_with_header(self):
1065-
"""Test loading facts from example CSV file with header."""
1066-
csv_path = 'tests/api_tests/test_files/example_facts.csv'
1067-
1068-
# Only run if example file exists
1069-
if os.path.exists(csv_path):
1070-
pr.add_fact_in_bulk(csv_path)
1071-
1072-
def test_add_fact_in_bulk_example_file_without_header(self):
1073-
"""Test loading facts from example CSV file without header."""
1074-
csv_path = 'tests/api_tests/test_files/example_facts_no_header.csv'
1075-
1076-
# Only run if example file exists
1077-
if os.path.exists(csv_path):
1078-
pr.add_fact_in_bulk(csv_path)
10791055

10801056

10811057
class TestRuleTrace:

0 commit comments

Comments
 (0)