11"""Unit tests for StringField class."""
22
3- import pytest
43
54from flowmapper .string_field import StringField
65
@@ -11,24 +10,33 @@ class TestStringFieldInitialization:
1110 def test_init_with_value (self ):
1211 """Test initialization with a value."""
1312 sf = StringField ("test" )
14- assert sf .value == "test" , f"Expected sf.value to be 'test', but got { sf .value !r} "
15- assert sf .use_lowercase is True , f"Expected sf.use_lowercase to be True, but got { sf .use_lowercase } "
16-
17- def test_init_with_value_and_use_lowercase_false (self ):
18- """Test initialization with use_lowercase=False."""
19- sf = StringField ("TEST" , use_lowercase = False )
20- assert sf .value == "TEST" , f"Expected sf.value to be 'TEST', but got { sf .value !r} "
21- assert sf .use_lowercase is False , f"Expected sf.use_lowercase to be False, but got { sf .use_lowercase } "
13+ assert sf == "test" , f"Expected sf to equal 'test', but got { sf !r} "
14+ from collections import UserString
15+ assert isinstance (sf , UserString ), f"Expected sf to be an instance of UserString, but got { type (sf )} "
16+ assert not isinstance (sf , str ), f"Expected sf to not be an instance of str (UserString is not a subclass), but got { type (sf )} "
2217
2318 def test_init_with_empty_string (self ):
2419 """Test initialization with empty string."""
2520 sf = StringField ("" )
26- assert sf .value == "" , f"Expected sf.value to be '', but got { sf .value !r} "
21+ # Empty StringField doesn't equal empty string due to __eq__ implementation
22+ assert sf != "" , f"Expected sf to not equal '', but they are equal (sf={ sf !r} )"
23+ assert sf .data == "" , f"Expected sf.data to be '', but got { sf .data !r} "
2724
2825 def test_init_with_whitespace (self ):
2926 """Test initialization with whitespace."""
3027 sf = StringField (" test " )
31- assert sf .value == " test " , f"Expected sf.value to be ' test ', but got { sf .value !r} "
28+ # Equality normalizes the other string, so " test " becomes "test"
29+ assert sf == " test " , f"Expected sf to equal ' test ', but got { sf !r} "
30+ assert sf .data == " test " , f"Expected sf.data to be ' test ', but got { sf .data !r} "
31+
32+ def test_inherits_from_userstring (self ):
33+ """Test that StringField inherits from UserString."""
34+ sf = StringField ("test" )
35+ from collections import UserString
36+ assert isinstance (sf , UserString ), f"Expected sf to be an instance of UserString, but got { type (sf )} "
37+ assert issubclass (StringField , UserString ), "Expected StringField to be a subclass of UserString, but it is not"
38+ # UserString is not a subclass of str
39+ assert not isinstance (sf , str ), f"Expected sf to not be an instance of str (UserString is not a subclass), but got { type (sf )} "
3240
3341
3442class TestStringFieldNormalize :
@@ -38,28 +46,27 @@ def test_normalize_with_lowercase_default(self):
3846 """Test normalize with default lowercase=True."""
3947 sf = StringField ("TEST" )
4048 normalized = sf .normalize ()
41- assert normalized . value == "test" , f"Expected normalized.value to be 'test', but got { normalized . value !r} "
42- assert normalized . use_lowercase is True , f"Expected normalized.use_lowercase to be True , but got { normalized . use_lowercase } "
49+ assert normalized == "test" , f"Expected normalized to equal 'test', but got { normalized !r} "
50+ assert isinstance ( normalized , StringField ) , f"Expected normalized to be a StringField instance , but got { type ( normalized ) } "
4351
4452 def test_normalize_with_lowercase_false (self ):
45- """Test normalize with use_lowercase=False."""
46- sf = StringField ("TEST" , use_lowercase = False )
47- normalized = sf .normalize ()
48- assert normalized .value == "TEST" , f"Expected normalized.value to be 'TEST', but got { normalized .value !r} "
49- assert normalized .use_lowercase is False , f"Expected normalized.use_lowercase to be False, but got { normalized .use_lowercase } "
53+ """Test normalize with lowercase=False."""
54+ sf = StringField ("TEST" )
55+ normalized = sf .normalize (lowercase = False )
56+ assert normalized == "TEST" , f"Expected normalized to equal 'TEST', but got { normalized !r} "
5057
5158 def test_normalize_with_whitespace (self ):
5259 """Test normalize with whitespace."""
5360 sf = StringField (" test " )
5461 normalized = sf .normalize ()
55- assert normalized . value == "test" , f"Expected normalized.value to be 'test', but got { normalized . value !r} "
62+ assert normalized == "test" , f"Expected normalized to equal 'test', but got { normalized !r} "
5663
5764 def test_normalize_returns_new_instance (self ):
5865 """Test that normalize returns a new instance."""
5966 sf = StringField ("TEST" )
6067 normalized = sf .normalize ()
6168 assert normalized is not sf , "Expected normalize() to return a new instance, but it returned the same instance"
62- assert sf . value == "TEST" , f"Expected original sf.value to remain 'TEST', but got { sf . value !r} "
69+ assert sf == "TEST" , f"Expected original sf to remain 'TEST', but got { sf !r} "
6370
6471
6572class TestStringFieldEq :
@@ -77,17 +84,11 @@ def test_eq_with_different_stringfield(self):
7784 sf2 = StringField ("other" )
7885 assert sf1 != sf2 , f"Expected sf1 to not equal sf2, but they are equal (sf1={ sf1 !r} , sf2={ sf2 !r} )"
7986
80- def test_eq_with_string_lowercase (self ):
81- """Test equality with string when use_lowercase=True ."""
82- sf = StringField ("TEST" , use_lowercase = True )
87+ def test_eq_with_string (self ):
88+ """Test equality with string."""
89+ sf = StringField ("test" )
8390 assert sf == "test" , f"Expected sf to equal 'test', but they are not equal (sf={ sf !r} )"
84- assert sf == "TEST" , f"Expected sf to equal 'TEST', but they are not equal (sf={ sf !r} )"
85-
86- def test_eq_with_string_no_lowercase (self ):
87- """Test equality with string when use_lowercase=False."""
88- sf = StringField ("TEST" , use_lowercase = False )
89- assert sf == "TEST" , f"Expected sf to equal 'TEST', but they are not equal (sf={ sf !r} )"
90- assert sf != "test" , f"Expected sf to not equal 'test', but they are equal (sf={ sf !r} )"
91+ assert sf != "other" , f"Expected sf to not equal 'other', but they are equal (sf={ sf !r} )"
9192
9293 def test_eq_with_empty_stringfield (self ):
9394 """Test equality with empty StringField."""
@@ -102,78 +103,51 @@ def test_eq_with_other_type(self):
102103 assert sf != None , f"Expected sf to not equal None, but they are equal (sf={ sf !r} )"
103104 assert sf != [], f"Expected sf to not equal [], but they are equal (sf={ sf !r} )"
104105
105- def test_eq_with_stringfield_different_lowercase_setting (self ):
106- """Test equality between StringFields with different use_lowercase settings."""
107- sf1 = StringField ("TEST" , use_lowercase = True )
108- sf2 = StringField ("TEST" , use_lowercase = False )
109- # They should be equal because they have the same value
110- assert sf1 == sf2 , f"Expected sf1 to equal sf2, but they are not equal (sf1={ sf1 !r} , sf2={ sf2 !r} )"
111106
107+ class TestStringFieldStrBehavior :
108+ """Test StringField string behavior (inherited from str)."""
112109
113- class TestStringFieldBool :
114- """Test StringField __bool__ method."""
110+ def test_str_operations (self ):
111+ """Test that StringField behaves like a string."""
112+ sf = StringField ("test" )
113+ assert len (sf ) == 4 , f"Expected len(sf) to be 4, but got { len (sf )} "
114+ assert sf .upper () == "TEST" , f"Expected sf.upper() to be 'TEST', but got { sf .upper ()!r} "
115+ assert sf .lower () == "test" , f"Expected sf.lower() to be 'test', but got { sf .lower ()!r} "
116+ assert sf .startswith ("te" ), f"Expected sf.startswith('te') to be True, but got { sf .startswith ('te' )} "
115117
116118 def test_bool_with_non_empty_string (self ):
117- """Test __bool__ with non-empty string."""
119+ """Test __bool__ with non-empty string (inherited from str) ."""
118120 sf = StringField ("test" )
119121 assert bool (sf ) is True , f"Expected bool(sf) to be True, but got { bool (sf )} "
120122
121123 def test_bool_with_empty_string (self ):
122- """Test __bool__ with empty string."""
124+ """Test __bool__ with empty string (inherited from str) ."""
123125 sf = StringField ("" )
124126 assert bool (sf ) is False , f"Expected bool(sf) to be False, but got { bool (sf )} "
125127
126128 def test_bool_with_whitespace (self ):
127- """Test __bool__ with whitespace-only string."""
129+ """Test __bool__ with whitespace-only string (inherited from str) ."""
128130 sf = StringField (" " )
129131 assert bool (sf ) is True , f"Expected bool(sf) to be True for whitespace, but got { bool (sf )} "
130132
131133
132- class TestStringFieldRepr :
133- """Test StringField __repr__ method."""
134-
135- def test_repr_with_value (self ):
136- """Test __repr__ with a value."""
137- sf = StringField ("test" )
138- expected = "StringField: 'test'"
139- assert repr (sf ) == expected , f"Expected repr(sf) to be { expected !r} , but got { repr (sf )!r} "
140-
141- def test_repr_with_empty_string (self ):
142- """Test __repr__ with empty string."""
143- sf = StringField ("" )
144- expected = "StringField with missing value"
145- assert repr (sf ) == expected , f"Expected repr(sf) to be { expected !r} , but got { repr (sf )!r} "
146-
147- def test_repr_with_special_characters (self ):
148- """Test __repr__ with special characters."""
149- sf = StringField ("test 'value'" )
150- expected = "StringField: 'test 'value''"
151- assert repr (sf ) == expected , f"Expected repr(sf) to be { expected !r} , but got { repr (sf )!r} "
152-
153- def test_repr_with_unicode (self ):
154- """Test __repr__ with unicode characters."""
155- sf = StringField ("café" )
156- expected = "StringField: 'café'"
157- assert repr (sf ) == expected , f"Expected repr(sf) to be { expected !r} , but got { repr (sf )!r} "
158-
159-
160134class TestStringFieldEdgeCases :
161135 """Test StringField edge cases."""
162136
163137 def test_value_preserved_after_normalize (self ):
164138 """Test that original value is preserved after normalize."""
165139 sf = StringField ("ORIGINAL" )
166140 normalized = sf .normalize ()
167- assert sf . value == "ORIGINAL" , f"Expected original sf.value to remain 'ORIGINAL', but got { sf . value !r} "
168- assert normalized . value == "original" , f"Expected normalized.value to be 'original', but got { normalized . value !r} "
141+ assert sf == "ORIGINAL" , f"Expected original sf to remain 'ORIGINAL', but got { sf !r} "
142+ assert normalized == "original" , f"Expected normalized to be 'original', but got { normalized !r} "
169143
170144 def test_multiple_normalize_calls (self ):
171145 """Test multiple normalize calls."""
172146 sf = StringField (" TEST " )
173147 norm1 = sf .normalize ()
174148 norm2 = norm1 .normalize ()
175- assert norm1 . value == "test" , f"Expected norm1.value to be 'test', but got { norm1 . value !r} "
176- assert norm2 . value == "test" , f"Expected norm2.value to be 'test', but got { norm2 . value !r} "
149+ assert norm1 == "test" , f"Expected norm1 to be 'test', but got { norm1 !r} "
150+ assert norm2 == "test" , f"Expected norm2 to be 'test', but got { norm2 !r} "
177151
178152 def test_equality_chain (self ):
179153 """Test equality chain with multiple StringFields."""
@@ -182,10 +156,21 @@ def test_equality_chain(self):
182156 sf3 = StringField ("test" )
183157 assert sf1 == sf2 == sf3 , f"Expected all StringFields to be equal, but they are not (sf1={ sf1 !r} , sf2={ sf2 !r} , sf3={ sf3 !r} )"
184158
185- def test_equality_with_normalized (self ):
186- """Test equality between original and normalized StringField."""
187- sf1 = StringField ("TEST" )
188- sf2 = sf1 .normalize ()
189- # They should be equal because they have the same value after normalization
190- assert sf1 == sf2 , f"Expected sf1 to equal normalized sf2, but they are not equal (sf1={ sf1 !r} , sf2={ sf2 !r} )"
159+ def test_normalize_with_different_lowercase_settings (self ):
160+ """Test normalize with different lowercase settings."""
161+ sf = StringField ("TEST" )
162+ norm1 = sf .normalize (lowercase = True )
163+ norm2 = sf .normalize (lowercase = False )
164+ assert norm1 == "test" , f"Expected norm1 to be 'test', but got { norm1 !r} "
165+ assert norm2 == "TEST" , f"Expected norm2 to be 'TEST', but got { norm2 !r} "
166+
167+ def test_string_concatenation (self ):
168+ """Test that StringField can be concatenated like a string."""
169+ sf1 = StringField ("hello" )
170+ sf2 = StringField ("world" )
171+ result = sf1 + " " + sf2
172+ assert result == "hello world" , f"Expected result to be 'hello world', but got { result !r} "
173+ # UserString concatenation returns a new instance of the same class
174+ assert isinstance (result , StringField ), f"Expected result to be a StringField instance, but got { type (result )} "
175+ assert result .data == "hello world" , f"Expected result.data to be 'hello world', but got { result .data !r} "
191176
0 commit comments