1+ using System ;
2+ using System . Data ;
3+ using System . Globalization ;
4+ using NUnit . Framework ;
5+ using System . Linq ;
6+
7+ namespace TypeGuesser . Tests
8+ {
9+ [ TestFixture ]
10+ public class AdditionalCoverageTests
11+ {
12+ [ Test ]
13+ public void GetSharedFactory_WithVariousCultures_ReturnsCorrectFactories ( )
14+ {
15+ // Test different cultures to cover the factory caching logic
16+ var cultures = new [ ]
17+ {
18+ CultureInfo . InvariantCulture ,
19+ new CultureInfo ( "en-US" ) ,
20+ new CultureInfo ( "fr-FR" ) ,
21+ new CultureInfo ( "de-DE" ) ,
22+ new CultureInfo ( "ja-JP" )
23+ } ;
24+
25+ foreach ( var factory in cultures . Select ( culture => Guesser . GetSharedFactory ( culture ) ) )
26+ {
27+ Assert . That ( factory , Is . Not . Null ) ;
28+ Assert . That ( factory . Settings , Is . Not . Null ) ;
29+ }
30+ }
31+
32+ [ Test ]
33+ public void GetSharedFactory_CachingBehavior_ReturnsSameInstances ( )
34+ {
35+ // Test that the same culture returns the same factory instance
36+ var culture = new CultureInfo ( "es-ES" ) ;
37+ var factory1 = Guesser . GetSharedFactory ( culture ) ;
38+ var factory2 = Guesser . GetSharedFactory ( culture ) ;
39+ var factory3 = Guesser . GetSharedFactory ( culture ) ;
40+
41+ Assert . That ( factory1 , Is . SameAs ( factory2 ) ) ;
42+ Assert . That ( factory2 , Is . SameAs ( factory3 ) ) ;
43+ }
44+
45+ [ Test ]
46+ public void DatabaseTypeRequest_Max_WithIncompatibleTypes_ThrowsNotSupportedException ( )
47+ {
48+ // Test the resource string path in DatabaseTypeRequest.Max
49+ var request1 = new DatabaseTypeRequest ( typeof ( Guid ) ) ;
50+ var request2 = new DatabaseTypeRequest ( typeof ( Type ) ) ;
51+
52+ var ex = Assert . Throws < NotSupportedException > ( ( ) => DatabaseTypeRequest . Max ( request1 , request2 ) ) ;
53+ Assert . That ( ex . Message , Does . Contain ( "Could not combine Types" ) ) ;
54+ }
55+
56+ [ Test ]
57+ public void Guesser_Dispose_MultipleCalls_Safe ( )
58+ {
59+ // Test that multiple dispose calls are safe
60+ using var guesser = new Guesser ( ) ;
61+ guesser . AdjustToCompensateForValue ( "test" ) ;
62+
63+ guesser . Dispose ( ) ;
64+ guesser . Dispose ( ) ; // Should not throw
65+ guesser . Dispose ( ) ; // Should not throw
66+
67+ Assert . Pass ( "Multiple dispose calls completed successfully" ) ;
68+ }
69+
70+ [ Test ]
71+ public void Guesser_DisposedAccess_ThrowsObjectDisposedException ( )
72+ {
73+ // Test accessing methods after dispose
74+ using var guesser = new Guesser ( ) ;
75+ guesser . AdjustToCompensateForValue ( "test" ) ;
76+ guesser . Dispose ( ) ;
77+
78+ Assert . Throws < ObjectDisposedException > ( ( ) => guesser . AdjustToCompensateForValue ( "123" ) ) ;
79+ }
80+
81+ [ Test ]
82+ public void Guesser_Parse_WithVariousTypes ( )
83+ {
84+ // Test the Parse method with different guess types
85+ using var guesser = new Guesser ( ) ;
86+
87+ // Test int parsing
88+ guesser . AdjustToCompensateForValue ( 42 ) ;
89+ var intResult = guesser . Parse ( "123" ) ;
90+ Assert . That ( intResult , Is . EqualTo ( 123 ) ) ;
91+
92+ // Reset for next test
93+ guesser . Dispose ( ) ;
94+ using var newGuesser = new Guesser ( ) ;
95+
96+ // Test decimal parsing
97+ newGuesser . AdjustToCompensateForValue ( 12.34m ) ;
98+ var decimalResult = newGuesser . Parse ( "56.78" ) ;
99+ Assert . That ( decimalResult , Is . EqualTo ( 56.78m ) ) ;
100+ }
101+
102+ [ Test ]
103+ public void Guesser_ShouldDowngradeColumnType_Logic ( )
104+ {
105+ // Test the ShouldDowngradeColumnTypeToMatchCurrentEstimate method
106+ using var guesser = new Guesser ( ) ;
107+ guesser . AdjustToCompensateForValue ( 42 ) ; // int type
108+
109+ using var table = new DataTable ( ) ;
110+ var stringColumn = table . Columns . Add ( "StringCol" , typeof ( string ) ) ;
111+ var objectColumn = table . Columns . Add ( "ObjectCol" , typeof ( object ) ) ;
112+ var intColumn = table . Columns . Add ( "IntCol" , typeof ( int ) ) ;
113+
114+ // Should downgrade string and object columns to int
115+ Assert . That ( guesser . ShouldDowngradeColumnTypeToMatchCurrentEstimate ( stringColumn ) , Is . True ) ;
116+ Assert . That ( guesser . ShouldDowngradeColumnTypeToMatchCurrentEstimate ( objectColumn ) , Is . True ) ;
117+
118+ // Should not change explicitly typed int column
119+ Assert . That ( guesser . ShouldDowngradeColumnTypeToMatchCurrentEstimate ( intColumn ) , Is . False ) ;
120+ }
121+
122+ [ Test ]
123+ public void Guesser_ExtraLengthPerNonAsciiCharacter_Property ( )
124+ {
125+ // Test the ExtraLengthPerNonAsciiCharacter property
126+ const int extraLength = 3 ;
127+ using var guesser = new Guesser { ExtraLengthPerNonAsciiCharacter = extraLength } ;
128+
129+ Assert . That ( guesser . ExtraLengthPerNonAsciiCharacter , Is . EqualTo ( extraLength ) ) ;
130+ }
131+
132+ [ Test ]
133+ public void DecimalTypeDecider_ParseErrors_ThrowFormatException ( )
134+ {
135+ // Test error handling in DecimalTypeDecider
136+ var decider = new TypeGuesser . Deciders . DecimalTypeDecider ( CultureInfo . InvariantCulture ) ;
137+
138+ var invalidInputs = new [ ]
139+ {
140+ "not_a_number" ,
141+ "12.34.56" ,
142+ "abc123" ,
143+ "12e" ,
144+ "1e+abc"
145+ } ;
146+
147+ foreach ( var input in invalidInputs )
148+ {
149+ Assert . Throws < FormatException > ( ( ) => decider . Parse ( input . AsSpan ( ) ) ) ;
150+ }
151+ }
152+
153+ [ Test ]
154+ public void DateTimeTypeDecider_ParseErrors_ThrowFormatException ( )
155+ {
156+ // Test error handling in DateTimeTypeDecider
157+ var decider = new TypeGuesser . Deciders . DateTimeTypeDecider ( CultureInfo . InvariantCulture ) ;
158+
159+ var invalidInputs = new [ ]
160+ {
161+ "not_a_date" ,
162+ "32/01/2023" ,
163+ "13/13/2023" ,
164+ "2023-99-99" ,
165+ "invalid_date_format"
166+ } ;
167+
168+ foreach ( var input in invalidInputs )
169+ {
170+ Assert . Throws < FormatException > ( ( ) => decider . Parse ( input . AsSpan ( ) ) ) ;
171+ }
172+ }
173+
174+ [ Test ]
175+ public void BoolTypeDecider_ParseErrors_ThrowFormatException ( )
176+ {
177+ // Test error handling in BoolTypeDecider
178+ var decider = new TypeGuesser . Deciders . BoolTypeDecider ( CultureInfo . InvariantCulture ) ;
179+
180+ var invalidInputs = new [ ]
181+ {
182+ "maybe" ,
183+ "unknown" ,
184+ "2" ,
185+ "onoff" ,
186+ "yesno"
187+ } ;
188+
189+ foreach ( var input in invalidInputs )
190+ {
191+ Assert . Throws < FormatException > ( ( ) => decider . Parse ( input . AsSpan ( ) ) ) ;
192+ }
193+ }
194+
195+ [ Test ]
196+ public void IntTypeDecider_ParseErrors_ThrowFormatException ( )
197+ {
198+ // Test error handling in IntTypeDecider
199+ var decider = new TypeGuesser . Deciders . IntTypeDecider ( CultureInfo . InvariantCulture ) ;
200+
201+ var invalidInputs = new [ ]
202+ {
203+ "12.34" ,
204+ "not_a_number" ,
205+ "999999999999999999999999999999" ,
206+ "1e100"
207+ } ;
208+
209+ foreach ( var input in invalidInputs )
210+ {
211+ Assert . Throws < FormatException > ( ( ) => decider . Parse ( input . AsSpan ( ) ) ) ;
212+ }
213+ }
214+
215+ [ Test ]
216+ public void MixedTyping_VariousScenarios_ThrowMixedTypingException ( )
217+ {
218+ // Test various mixed typing scenarios
219+ var scenarios = new object [ ]
220+ {
221+ "string" , 42 ,
222+ true , "test" ,
223+ 12.34m , false ,
224+ DateTime . Now , "date"
225+ } ;
226+
227+ for ( int i = 0 ; i < scenarios . Length ; i += 2 )
228+ {
229+ using var guesser = new Guesser ( ) ;
230+ guesser . AdjustToCompensateForValue ( scenarios [ i ] ) ;
231+
232+ Assert . Throws < MixedTypingException > ( ( ) =>
233+ guesser . AdjustToCompensateForValue ( scenarios [ i + 1 ] ) ) ;
234+ }
235+ }
236+
237+ [ Test ]
238+ public void TypeDeciderFactory_UnsupportedTypes_ThrowException ( )
239+ {
240+ // Test TypeDeciderFactory with unsupported types
241+ var factory = new TypeDeciderFactory ( CultureInfo . InvariantCulture ) ;
242+ var unsupportedTypes = new [ ]
243+ {
244+ typeof ( AdditionalCoverageTests ) ,
245+ typeof ( Exception ) ,
246+ typeof ( AdditionalCoverageTests ) ,
247+ typeof ( Action ) ,
248+ typeof ( Func < int > )
249+ } ;
250+
251+ foreach ( var type in unsupportedTypes )
252+ {
253+ Assert . Catch < Exception > ( ( ) => factory . Create ( type ) ) ;
254+ }
255+ }
256+
257+ [ Test ]
258+ public void Constructor_WithDatabaseTypeRequest_HandlesVariousTypes ( )
259+ {
260+ // Test Guesser constructor with different DatabaseTypeRequest types
261+ var requests = new [ ]
262+ {
263+ new DatabaseTypeRequest ( typeof ( int ) ) ,
264+ new DatabaseTypeRequest ( typeof ( decimal ) ) ,
265+ new DatabaseTypeRequest ( typeof ( string ) ) ,
266+ new DatabaseTypeRequest ( typeof ( DateTime ) )
267+ } ;
268+
269+ foreach ( var request in requests )
270+ {
271+ using var guesser = new Guesser ( request ) ;
272+ Assert . That ( guesser . Guess . CSharpType , Is . EqualTo ( request . CSharpType ) ) ;
273+ }
274+ }
275+ }
276+ }
0 commit comments