"""Test cases for the RKey and TID classes in atpasser.uri.rkey module.""" import pytest import datetime from atpasser.uri.rkey import RKey, TID, importTIDfromInteger, importTIDfromBase32 from atpasser.uri.exceptions import InvalidRKeyError class TestRKey: """Test cases for the RKey class.""" def test_valid_rkey_simple(self): """Test creating an RKey with a valid simple format.""" rkey_str = "3jui7kd54zh2y" rkey = RKey(rkey_str) assert str(rkey) == rkey_str assert rkey.recordKey == rkey_str def test_valid_rkey_with_various_characters(self): """Test creating an RKey with various valid characters.""" rkey_str = "example.com" rkey = RKey(rkey_str) assert str(rkey) == rkey_str assert rkey.recordKey == rkey_str def test_valid_rkey_with_special_characters(self): """Test creating an RKey with valid special characters.""" rkey_str = "~1.2-3_" rkey = RKey(rkey_str) assert str(rkey) == rkey_str assert rkey.recordKey == rkey_str def test_valid_rkey_with_colon(self): """Test creating an RKey with a colon.""" rkey_str = "pre:fix" rkey = RKey(rkey_str) assert str(rkey) == rkey_str assert rkey.recordKey == rkey_str def test_valid_rkey_underscore(self): """Test creating an RKey with just an underscore.""" rkey_str = "_" rkey = RKey(rkey_str) assert str(rkey) == rkey_str assert rkey.recordKey == rkey_str def test_invalid_rkey_empty(self): """Test that an empty RKey raises InvalidRKeyError.""" rkey_str = "" with pytest.raises(InvalidRKeyError, match="record key is empty"): RKey(rkey_str) def test_invalid_rkey_too_long(self): """Test that an RKey that is too long raises InvalidRKeyError.""" # Create an RKey that exceeds the 512 character limit rkey_str = "a" * 513 with pytest.raises(InvalidRKeyError, match="exceeds maximum length"): RKey(rkey_str) def test_invalid_rkey_reserved_double_dot(self): """Test that an RKey with '..' raises InvalidRKeyError.""" rkey_str = ".." with pytest.raises(InvalidRKeyError, match="reserved value"): RKey(rkey_str) def test_invalid_rkey_reserved_single_dot(self): """Test that an RKey with '.' raises InvalidRKeyError.""" rkey_str = "." with pytest.raises(InvalidRKeyError, match="reserved value"): RKey(rkey_str) def test_invalid_rkey_invalid_characters(self): """Test that an RKey with invalid characters raises InvalidRKeyError.""" rkey_str = "alpha/beta" with pytest.raises(InvalidRKeyError, match="contains invalid characters"): RKey(rkey_str) def test_invalid_rkey_hash_character(self): """Test that an RKey with a hash character raises InvalidRKeyError.""" rkey_str = "#extra" with pytest.raises(InvalidRKeyError, match="contains invalid characters"): RKey(rkey_str) def test_invalid_rkey_at_character(self): """Test that an RKey with an at character raises InvalidRKeyError.""" rkey_str = "@handle" with pytest.raises(InvalidRKeyError, match="contains invalid characters"): RKey(rkey_str) def test_invalid_rkey_space(self): """Test that an RKey with a space raises InvalidRKeyError.""" rkey_str = "any space" with pytest.raises(InvalidRKeyError, match="contains invalid characters"): RKey(rkey_str) def test_invalid_rkey_plus_character(self): """Test that an RKey with a plus character raises InvalidRKeyError.""" rkey_str = "any+space" with pytest.raises(InvalidRKeyError, match="contains invalid characters"): RKey(rkey_str) def test_invalid_rkey_brackets(self): """Test that an RKey with brackets raises InvalidRKeyError.""" rkey_str = "number[3]" with pytest.raises(InvalidRKeyError, match="contains invalid characters"): RKey(rkey_str) def test_invalid_rkey_parentheses(self): """Test that an RKey with parentheses raises InvalidRKeyError.""" rkey_str = "number(3)" with pytest.raises(InvalidRKeyError, match="contains invalid characters"): RKey(rkey_str) def test_invalid_rkey_quotes(self): """Test that an RKey with quotes raises InvalidRKeyError.""" rkey_str = '"quote"' with pytest.raises(InvalidRKeyError, match="contains invalid characters"): RKey(rkey_str) def test_invalid_rkey_base64_padding(self): """Test that an RKey with base64 padding raises InvalidRKeyError.""" rkey_str = "dHJ1ZQ==" with pytest.raises(InvalidRKeyError, match="contains invalid characters"): RKey(rkey_str) def test_rkey_equality(self): """Test RKey equality comparison.""" rkey_str = "3jui7kd54zh2y" rkey1 = RKey(rkey_str) rkey2 = RKey(rkey_str) assert rkey1 == rkey2 assert rkey1 != "not an rkey object" def test_rkey_string_representation(self): """Test RKey string representation.""" rkey_str = "3jui7kd54zh2y" rkey = RKey(rkey_str) assert str(rkey) == rkey_str class TestTID: """Test cases for the TID class.""" def test_tid_creation_default(self): """Test creating a TID with default parameters.""" tid = TID() assert isinstance(tid, TID) assert isinstance(tid, RKey) assert isinstance(tid.timestamp, datetime.datetime) assert isinstance(tid.clockIdentifier, int) assert 0 <= tid.clockIdentifier < 1024 assert len(str(tid)) == 13 # TID string is always 13 characters def test_tid_creation_with_timestamp(self): """Test creating a TID with a specific timestamp.""" timestamp = datetime.datetime(2023, 1, 1, 12, 0, 0) tid = TID(time=timestamp) assert tid.timestamp == timestamp assert isinstance(tid.clockIdentifier, int) assert 0 <= tid.clockIdentifier < 1024 def test_tid_creation_with_clock_identifier(self): """Test creating a TID with a specific clock identifier.""" clock_id = 42 tid = TID(clockIdentifier=clock_id) assert tid.clockIdentifier == clock_id assert isinstance(tid.timestamp, datetime.datetime) def test_tid_creation_with_both_parameters(self): """Test creating a TID with both timestamp and clock identifier.""" timestamp = datetime.datetime(2023, 1, 1, 12, 0, 0) clock_id = 42 tid = TID(time=timestamp, clockIdentifier=clock_id) assert tid.timestamp == timestamp assert tid.clockIdentifier == clock_id def test_tid_integer_representation(self): """Test TID integer representation.""" timestamp = datetime.datetime(2023, 1, 1, 12, 0, 0) clock_id = 42 tid = TID(time=timestamp, clockIdentifier=clock_id) int_value = int(tid) expected_value = int(timestamp.timestamp() * 1000000) * 1024 + clock_id assert int_value == expected_value def test_tid_string_representation(self): """Test TID string representation.""" tid = TID() str_value = str(tid) assert len(str_value) == 13 assert all(c in "234567abcdefghijklmnopqrstuvwxyz" for c in str_value) def test_tid_equality_with_tid(self): """Test TID equality comparison with another TID.""" timestamp = datetime.datetime(2023, 1, 1, 12, 0, 0) clock_id = 42 tid1 = TID(time=timestamp, clockIdentifier=clock_id) tid2 = TID(time=timestamp, clockIdentifier=clock_id) assert tid1 == tid2 def test_tid_equality_with_rkey(self): """Test TID equality comparison with an RKey.""" timestamp = datetime.datetime(2023, 1, 1, 12, 0, 0) clock_id = 42 tid = TID(time=timestamp, clockIdentifier=clock_id) rkey = RKey(str(tid)) assert tid == rkey def test_tid_inequality_with_different_object(self): """Test TID inequality comparison with a different object type.""" tid = TID() assert tid != "not a tid object" def test_tid_inequality_with_different_timestamp(self): """Test TID inequality comparison with different timestamp.""" timestamp1 = datetime.datetime(2023, 1, 1, 12, 0, 0) timestamp2 = datetime.datetime(2023, 1, 1, 12, 0, 1) clock_id = 42 tid1 = TID(time=timestamp1, clockIdentifier=clock_id) tid2 = TID(time=timestamp2, clockIdentifier=clock_id) assert tid1 != tid2 def test_tid_inequality_with_different_clock_id(self): """Test TID inequality comparison with different clock identifier.""" timestamp = datetime.datetime(2023, 1, 1, 12, 0, 0) clock_id1 = 42 clock_id2 = 43 tid1 = TID(time=timestamp, clockIdentifier=clock_id1) tid2 = TID(time=timestamp, clockIdentifier=clock_id2) assert tid1 != tid2 class TestTIDImportFunctions: """Test cases for TID import functions.""" def test_import_tid_from_integer_default(self): """Test importing a TID from integer with default value.""" tid = importTIDfromInteger() assert isinstance(tid, TID) assert isinstance(tid.timestamp, datetime.datetime) assert isinstance(tid.clockIdentifier, int) assert 0 <= tid.clockIdentifier < 1024 def test_import_tid_from_integer_with_value(self): """Test importing a TID from integer with a specific value.""" timestamp = datetime.datetime(2023, 1, 1, 12, 0, 0) clock_id = 42 original_tid = TID(time=timestamp, clockIdentifier=clock_id) int_value = int(original_tid) imported_tid = importTIDfromInteger(int_value) assert imported_tid.timestamp == timestamp assert imported_tid.clockIdentifier == clock_id def test_import_tid_from_base32_default(self): """Test importing a TID from base32 with default value.""" tid = importTIDfromBase32() assert isinstance(tid, TID) assert isinstance(tid.timestamp, datetime.datetime) assert isinstance(tid.clockIdentifier, int) assert 0 <= tid.clockIdentifier < 1024 def test_import_tid_from_base32_with_value(self): """Test importing a TID from base32 with a specific value.""" original_tid = TID() str_value = str(original_tid) imported_tid = importTIDfromBase32(str_value) assert int(imported_tid) == int(original_tid)