import pytest
import tempfile
import shutil
from pathlib import Path
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'apexbase', 'python'))
try:
from apexbase import ApexClient
except ImportError as e:
pytest.skip(f"ApexBase not available: {e}", allow_module_level=True)
class TestColumnAddition:
def test_add_column_basic(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
client.store({"name": "Alice", "age": 25})
try:
client.add_column("city", "string")
except Exception as e:
print(f"add_column: {e}")
client.store({"name": "Bob", "age": 30, "city": "NYC"})
result = client.retrieve(2)
assert result is not None
if "city" in result:
assert result["city"] == "NYC"
client.close()
def test_add_column_different_types(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
client.store({"name": "Alice"})
try:
client.add_column("age", "integer")
client.add_column("salary", "float")
client.add_column("active", "boolean")
client.add_column("notes", "string")
except Exception as e:
print(f"add_column types: {e}")
client.store({
"name": "Bob",
"age": 30,
"salary": 50000.50,
"active": True,
"notes": "Test employee"
})
result = client.retrieve(2)
assert result is not None
assert result["age"] == 30
assert result["salary"] == 50000.50
assert result["active"] is True
assert result["notes"] == "Test employee"
client.close()
def test_add_column_with_existing_data(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
test_data = [
{"name": "Alice", "age": 25},
{"name": "Bob", "age": 30},
{"name": "Charlie", "age": 35},
]
client.store(test_data)
try:
client.add_column("city", "string")
except Exception as e:
print(f"add_column with data: {e}")
client.store({"name": "Diana", "age": 28, "city": "Boston"})
diana = client.retrieve(4)
assert diana is not None
assert diana["name"] == "Diana"
if "city" in diana:
assert diana["city"] == "Boston"
client.close()
def test_add_column_duplicate_name(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
client.store({"name": "Alice", "age": 25})
try:
client.add_column("name", "string")
except Exception as e:
print(f"Duplicate column handled: {e}")
result = client.retrieve(1)
assert result is not None
assert result["name"] == "Alice"
client.close()
def test_add_column_invalid_type(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
client.store({"name": "Alice"})
try:
client.add_column("invalid_col", "invalid_type")
except Exception as e:
print(f"Invalid type handled: {e}")
result = client.retrieve(1)
assert result is not None
assert result["name"] == "Alice"
client.close()
def test_add_column_special_characters(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
client.store({"name": "Alice"})
special_names = [
"column_with_underscores",
"column-with-dashes",
"column.with.dots",
"columnWithCamelCase",
"column_with_numbers123",
]
for col_name in special_names:
try:
client.add_column(col_name, "string")
fields = client.list_fields()
assert col_name in fields
except Exception as e:
print(f"Column name '{col_name}' not supported: {e}")
client.close()
def test_add_column_unicode_name(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
client.store({"name": "Alice"})
unicode_names = [
"列名", "колонка", "colonne", ]
for col_name in unicode_names:
try:
client.add_column(col_name, "string")
fields = client.list_fields()
assert col_name in fields
except Exception as e:
print(f"Unicode column name '{col_name}' not supported: {e}")
client.close()
class TestColumnDeletion:
def test_drop_column_basic(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
client.store({"name": "Alice", "age": 25, "city": "NYC", "salary": 50000})
try:
client.drop_column("city")
result = client.retrieve(1)
if result is not None:
assert "name" in result
assert "age" in result
except Exception as e:
print(f"drop_column: {e}")
client.close()
def test_drop_nonexistent_column(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
client.store({"name": "Alice", "age": 25})
try:
client.drop_column("nonexistent_column")
except Exception as e:
print(f"Drop nonexistent: {e}")
result = client.retrieve(1)
assert result is not None
assert result["name"] == "Alice"
client.close()
def test_drop_id_column(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
client.store({"name": "Alice", "age": 25})
with pytest.raises(ValueError, match="Cannot drop _id column"):
client.drop_column("_id")
result = client.retrieve(1)
client.close()
def test_drop_multiple_columns(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
client.store({
"name": "Alice",
"age": 25,
"city": "NYC",
"salary": 50000,
"department": "Engineering",
"active": True
})
try:
client.drop_column("city")
client.drop_column("salary")
client.drop_column("department")
except Exception as e:
print(f"Drop multiple: {e}")
result = client.retrieve(1)
assert result is not None
assert result["name"] == "Alice"
client.close()
def test_drop_column_with_data(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
test_data = [
{"name": "Alice", "age": 25, "city": "NYC"},
{"name": "Bob", "age": 30, "city": "LA"},
{"name": "Charlie", "age": 35, "city": "Chicago"},
]
client.store(test_data)
try:
client.drop_column("city")
except Exception as e:
print(f"Drop with data: {e}")
for i in range(3):
result = client.retrieve(i + 1)
assert result is not None
assert "name" in result
assert "age" in result
client.close()
class TestColumnRenaming:
def test_rename_column_basic(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
client.store({"name": "Alice", "age": 25, "city": "NYC"})
try:
client.rename_column("city", "location")
result = client.retrieve(1)
assert result is not None
except Exception as e:
print(f"rename_column: {e}")
client.close()
def test_rename_nonexistent_column(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
client.store({"name": "Alice", "age": 25})
try:
client.rename_column("nonexistent_column", "new_name")
except Exception as e:
print(f"Rename nonexistent: {e}")
result = client.retrieve(1)
assert result is not None
assert result["name"] == "Alice"
client.close()
def test_rename_to_existing_column(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
client.store({"name": "Alice", "age": 25, "city": "NYC"})
try:
client.rename_column("age", "name")
except Exception as e:
print(f"Rename to existing: {e}")
result = client.retrieve(1)
assert result is not None
client.close()
def test_rename_id_column(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
client.store({"name": "Alice", "age": 25})
with pytest.raises(ValueError, match="Cannot rename _id column"):
client.rename_column("_id", "new_id")
result = client.retrieve(1)
client.close()
def test_rename_column_with_data(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
test_data = [
{"name": "Alice", "age": 25, "city": "NYC"},
{"name": "Bob", "age": 30, "city": "LA"},
{"name": "Charlie", "age": 35, "city": "Chicago"},
]
client.store(test_data)
try:
client.rename_column("city", "location")
except Exception as e:
print(f"Rename with data: {e}")
for i in range(3):
result = client.retrieve(i + 1)
assert result is not None
assert "name" in result
client.close()
def test_rename_column_special_characters(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
client.store({"name": "Alice", "age": 25})
try:
client.rename_column("age", "new_age_with_underscores")
fields = client.list_fields()
assert "new_age_with_underscores" in fields
assert "age" not in fields
result = client.retrieve(1)
assert result["new_age_with_underscores"] == 25
except Exception as e:
print(f"Special character rename not supported: {e}")
client.close()
class TestColumnDataTypeRetrieval:
def test_get_column_dtype_basic(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
client.store({
"name": "Alice",
"age": 25,
"salary": 50000.50,
"active": True,
"notes": "Test notes"
})
try:
name_type = client.get_column_dtype("name")
assert name_type is not None
except Exception as e:
print(f"get_column_dtype: {e}")
client.close()
def test_get_column_dtype_added_columns(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
client.store({"name": "Alice"})
try:
client.add_column("age", "integer")
age_type = client.get_column_dtype("age")
assert age_type is not None
except Exception as e:
print(f"get_column_dtype added: {e}")
client.close()
def test_get_column_dtype_nonexistent(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
client.store({"name": "Alice", "age": 25})
try:
dtype = client.get_column_dtype("nonexistent_column")
except Exception as e:
print(f"Get dtype nonexistent: {e}")
client.close()
def test_get_column_dtype_after_rename(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
client.store({"name": "Alice", "age": 25})
try:
client.rename_column("age", "user_age")
user_age_type = client.get_column_dtype("user_age")
assert user_age_type is not None
except Exception as e:
print(f"Dtype after rename: {e}")
client.close()
class TestColumnOperationsEdgeCases:
def test_column_operations_on_closed_client(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
client.close()
with pytest.raises(RuntimeError, match="connection has been closed"):
client.add_column("new_col", "string")
with pytest.raises(RuntimeError, match="connection has been closed"):
client.drop_column("name")
with pytest.raises(RuntimeError, match="connection has been closed"):
client.rename_column("name", "new_name")
with pytest.raises(RuntimeError, match="connection has been closed"):
client.get_column_dtype("name")
def test_column_operations_empty_table(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
try:
client.add_column("new_column", "string")
except Exception as e:
print(f"add_column empty: {e}")
client.store({"test": "data"})
result = client.retrieve(1)
assert result is not None
client.close()
def test_column_operations_with_fts(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
client.init_fts(index_fields=['content'])
client.store({"content": "Searchable text", "metadata": "not indexed"})
client.add_column("category", "string")
results = client.search_text("searchable")
assert len(results) > 0
client.drop_column("metadata")
results = client.search_text("searchable")
assert len(results) > 0
client.close()
def test_column_operations_large_dataset(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
large_data = [{"id": i, "value": f"item_{i}"} for i in range(1000)]
client.store(large_data)
import time
start_time = time.time()
try:
client.add_column("category", "string")
except Exception as e:
print(f"add_column large: {e}")
add_time = time.time() - start_time
assert add_time < 10.0
result = client.retrieve(1)
assert result is not None
assert result["id"] == 0
client.close()
def test_column_operations_with_various_data(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
test_data = {
"string_field": "test_string",
"int_field": 42,
"float_field": 3.14159,
"bool_field": True,
}
client.store(test_data)
try:
client.add_column("new_field", "string")
except Exception as e:
print(f"add_column various: {e}")
result = client.retrieve(1)
assert result is not None
assert result["string_field"] == "test_string"
assert result["int_field"] == 42
client.close()
def test_column_operations_across_tables(self):
with tempfile.TemporaryDirectory() as temp_dir:
client = ApexClient(dirpath=temp_dir)
client.create_table("default")
client.store({"name": "Alice", "age": 25})
client.create_table("users")
client.store({"username": "bob123", "email": "bob@example.com"})
client.use_table("default")
try:
client.add_column("city", "string")
except Exception as e:
print(f"add_column across: {e}")
client.use_table("default")
result = client.retrieve(1)
assert result is not None
assert result["name"] == "Alice"
client.use_table("users")
result = client.retrieve(1)
assert result is not None
assert result["username"] == "bob123"
client.close()
if __name__ == "__main__":
pytest.main([__file__, "-v"])