1
+ using System ;
2
+ using System . ComponentModel ;
3
+ using System . ComponentModel . DataAnnotations ;
4
+ using System . Diagnostics . CodeAnalysis ;
5
+ using System . Linq ;
6
+
7
+ using JetBrains . Annotations ;
8
+
9
+ using NUnit . Framework ;
10
+
11
+ using static NUnit . Framework . Assert ;
12
+
13
+ namespace CodeJam . ConnectionStrings
14
+ {
15
+ [ SuppressMessage ( "ReSharper" , "ObjectCreationAsStatement" ) ]
16
+ public class ConnectionStringTests
17
+ {
18
+ private static readonly DateTimeOffset _defaultDateTimeOffset = new DateTimeOffset (
19
+ new DateTime ( 2010 , 11 , 12 ) ,
20
+ TimeSpan . Zero ) ;
21
+
22
+ public class BaseConnectionString : ConnectionStringBase
23
+ {
24
+ public BaseConnectionString ( string connectionString ) : base ( connectionString ) { }
25
+
26
+ #if NET35_OR_GREATER || TARGETS_NETCOREAPP
27
+ [ Required ]
28
+ #endif
29
+ public string RequiredValue
30
+ {
31
+ get => TryGetValue ( nameof ( RequiredValue ) ) ;
32
+ set => SetValue ( nameof ( RequiredValue ) , value ) ;
33
+ }
34
+
35
+ public bool BooleanValue
36
+ {
37
+ get => TryGetBooleanValue ( nameof ( BooleanValue ) ) ;
38
+ set => SetValue ( nameof ( BooleanValue ) , value ) ;
39
+ }
40
+
41
+ public int ? Int32Value
42
+ {
43
+ get => TryGetInt32Value ( nameof ( Int32Value ) ) ;
44
+ set => SetValue ( nameof ( Int32Value ) , value ) ;
45
+ }
46
+ }
47
+
48
+ public class DerivedConnectionString : BaseConnectionString
49
+ {
50
+ public DerivedConnectionString ( string connectionString ) : base ( connectionString ) { }
51
+
52
+ public new string RequiredValue
53
+ {
54
+ get => TryGetValue ( nameof ( RequiredValue ) ) ;
55
+ set => SetValue ( nameof ( RequiredValue ) , value ) ;
56
+ }
57
+
58
+ // Never filled. Used to test roundtrip scenario
59
+ [ UsedImplicitly ]
60
+ public string OptionalValue
61
+ {
62
+ get => TryGetValue ( nameof ( OptionalValue ) ) ;
63
+ set => SetValue ( nameof ( OptionalValue ) , value ) ;
64
+ }
65
+
66
+ public DateTimeOffset ? DateTimeOffsetValue
67
+ {
68
+ get => TryGetDateTimeOffsetValue ( nameof ( DateTimeOffsetValue ) ) ;
69
+ set => SetValue ( nameof ( DateTimeOffsetValue ) , value ) ;
70
+ }
71
+ }
72
+
73
+ public class NonBrowsableConnectionString : BaseConnectionString
74
+ {
75
+ public NonBrowsableConnectionString ( string connectionString ) : base ( connectionString ) { }
76
+
77
+ [ Browsable ( false ) ]
78
+ public new string RequiredValue
79
+ {
80
+ get => TryGetValue ( nameof ( RequiredValue ) ) ;
81
+ set => SetValue ( nameof ( RequiredValue ) , value ) ;
82
+ }
83
+ }
84
+
85
+ [ Test ]
86
+ public void TestConnectionStringValidation ( )
87
+ {
88
+ DoesNotThrow ( ( ) => new BaseConnectionString ( null ) ) ;
89
+ DoesNotThrow ( ( ) => new BaseConnectionString ( "" ) ) ;
90
+ DoesNotThrow ( ( ) => new BaseConnectionString ( "requiredValue=aaa" ) ) ;
91
+ DoesNotThrow ( ( ) => new BaseConnectionString ( "RequiredValue=aaa;IgnoredValue=123" ) ) ;
92
+ DoesNotThrow ( ( ) => new BaseConnectionString ( "" ) { ConnectionString = null } ) ;
93
+ DoesNotThrow ( ( ) => new BaseConnectionString ( "" ) { ConnectionString = "" } ) ;
94
+ DoesNotThrow ( ( ) => new BaseConnectionString ( "" ) { ConnectionString = "requiredValue=aaa" } ) ;
95
+ DoesNotThrow ( ( ) => new BaseConnectionString ( "" ) { ConnectionString = "RequiredValue=aaa;IgnoredValue=123" } ) ;
96
+
97
+ #if NET35_OR_GREATER || TARGETS_NETCOREAPP
98
+ var ex = Throws < ArgumentException > ( ( ) => new BaseConnectionString ( "IgnoredValue=123" ) ) ;
99
+ That ( ex . Message , Does . Contain ( nameof ( BaseConnectionString . RequiredValue ) ) ) ;
100
+ ex = Throws < ArgumentException > (
101
+ ( ) => new BaseConnectionString ( "" )
102
+ {
103
+ ConnectionString = "IgnoredValue = 123"
104
+ } ) ;
105
+ That ( ex . Message , Does . Contain ( nameof ( BaseConnectionString . RequiredValue ) ) ) ;
106
+ #else
107
+ DoesNotThrow ( ( ) => new BaseConnectionString ( "IgnoredValue=123" ) ) ;
108
+ DoesNotThrow (
109
+ ( ) => new BaseConnectionString ( "" )
110
+ {
111
+ ConnectionString = "IgnoredValue = 123"
112
+ } ) ; ;
113
+ #endif
114
+ }
115
+
116
+ [ Test ]
117
+ public void TestConnectionStringValidationOverride ( )
118
+ {
119
+ DoesNotThrow ( ( ) => new DerivedConnectionString ( "IgnoredValue=123" ) ) ;
120
+ DoesNotThrow (
121
+ ( ) => new DerivedConnectionString ( "" )
122
+ {
123
+ ConnectionString = "IgnoredValue=123"
124
+ } ) ;
125
+ }
126
+
127
+ [ Test ]
128
+ public void TestGetProperties ( )
129
+ {
130
+ var x = new BaseConnectionString ( "requiredValue=aaa" ) ;
131
+ AreEqual ( x . RequiredValue , "aaa" ) ;
132
+ AreEqual ( x . BooleanValue , false ) ;
133
+ AreEqual ( x . Int32Value , null ) ;
134
+
135
+ IsTrue ( x . ContainsKey ( nameof ( x . RequiredValue ) ) ) ;
136
+ IsTrue ( x . TryGetValue ( nameof ( x . RequiredValue ) , out _ ) ) ;
137
+ AreEqual ( x [ nameof ( x . RequiredValue ) ] , "aaa" ) ;
138
+
139
+ x = new BaseConnectionString ( "requiredValue='aa; a'" ) ;
140
+ AreEqual ( x . RequiredValue , "aa; a" ) ;
141
+
142
+ x = new BaseConnectionString ( "requiredValue=\" aa; a\" " ) ;
143
+ AreEqual ( x . RequiredValue , "aa; a" ) ;
144
+
145
+ // test for input string format
146
+ x = new BaseConnectionString ( @"
147
+ RequiredValue=""aaa"" ;
148
+ BooleanValue=true;
149
+ Int32Value = 112" ) ;
150
+ AreEqual ( x . RequiredValue , "aaa" ) ;
151
+ AreEqual ( x . BooleanValue , true ) ;
152
+ AreEqual ( x . Int32Value , 112 ) ;
153
+ }
154
+
155
+ [ Test ]
156
+ public void TestGetPropertiesDerived ( )
157
+ {
158
+ var x = new DerivedConnectionString ( "IgnoredValue=aaa" ) ;
159
+ AreEqual ( x . RequiredValue , null ) ;
160
+ AreEqual ( x . OptionalValue , null ) ;
161
+ AreEqual ( x . BooleanValue , false ) ;
162
+ AreEqual ( x . Int32Value , null ) ;
163
+ AreEqual ( x . DateTimeOffsetValue , null ) ;
164
+
165
+ x = new DerivedConnectionString ( "DateTimeOffsetValue=2010-11-12Z" ) ;
166
+ AreEqual ( x . DateTimeOffsetValue , _defaultDateTimeOffset ) ;
167
+ }
168
+
169
+ [ Test ]
170
+ public void TestPropertiesRoundtrip ( )
171
+ {
172
+ var x = new DerivedConnectionString ( "" )
173
+ {
174
+ RequiredValue = "A; B=C'\" " ,
175
+ BooleanValue = true ,
176
+ Int32Value = - 1024 ,
177
+ DateTimeOffsetValue = _defaultDateTimeOffset
178
+ } ;
179
+
180
+ var s = x . ToString ( ) ;
181
+ AreEqual (
182
+ s ,
183
+ @"RequiredValue=""A; B=C'"""""";BooleanValue=True;Int32Value=-1024;DateTimeOffsetValue=""11/12/2010 00:00:00 +00:00""" ) ;
184
+
185
+ var x2 = new DerivedConnectionString ( s ) ;
186
+ AreEqual ( x2 . RequiredValue , x . RequiredValue ) ;
187
+ AreEqual ( x2 . BooleanValue , x . BooleanValue ) ;
188
+ AreEqual ( x2 . Int32Value , x . Int32Value ) ;
189
+ AreEqual ( x2 . DateTimeOffsetValue , x . DateTimeOffsetValue ) ;
190
+
191
+ AreEqual ( s , x2 . ToString ( ) ) ;
192
+ IsTrue ( x . EquivalentTo ( x2 ) ) ;
193
+ AreEqual ( x . OrderBy ( p => p . Key ) , x2 . OrderBy ( p => p . Key ) ) ;
194
+ }
195
+
196
+ [ Test ]
197
+ public void TestIgnoredProperties ( )
198
+ {
199
+ var x = new DerivedConnectionString ( "" ) ;
200
+ IsFalse ( x . ContainsKey ( "IgnoredValue" ) ) ;
201
+ IsFalse ( x . TryGetValue ( "IgnoredValue" , out var ignored ) ) ;
202
+ IsNull ( ignored ) ;
203
+ var ex = Throws < ArgumentException > ( ( ) => x [ "IgnoredValue" ] . ToString ( ) ) ;
204
+ That ( ex . Message , Does . Contain ( "IgnoredValue" ) ) ;
205
+
206
+ x = new DerivedConnectionString ( "IgnoredValue=123" ) ;
207
+ IsFalse ( x . ContainsKey ( "IgnoredValue" ) ) ;
208
+ IsFalse ( x . TryGetValue ( "IgnoredValue" , out ignored ) ) ;
209
+ IsNull ( ignored ) ;
210
+ ex = Throws < ArgumentException > ( ( ) => x [ "IgnoredValue" ] . ToString ( ) ) ;
211
+ That ( ex . Message , Does . Contain ( "IgnoredValue" ) ) ;
212
+ }
213
+
214
+ [ Test ]
215
+ public void TestInvalidProperties ( )
216
+ {
217
+ var x = new DerivedConnectionString ( @"BooleanValue=aaa;Int32Value=bbb;DateTimeOffsetValue=ccc" ) ;
218
+ Throws < FormatException > ( ( ) => x . BooleanValue . ToString ( ) ) ;
219
+ Throws < FormatException > ( ( ) => x . Int32Value ? . ToString ( ) ) ;
220
+ Throws < FormatException > ( ( ) => x . DateTimeOffsetValue ? . ToString ( ) ) ;
221
+ }
222
+
223
+ [ Test ]
224
+ public void TestNonBrowsableProperties ( )
225
+ {
226
+ var x = new NonBrowsableConnectionString ( "" )
227
+ {
228
+ RequiredValue = "A" ,
229
+ BooleanValue = true ,
230
+ Int32Value = - 1024
231
+ } ;
232
+
233
+ var s = x . GetBrowsableConnectionString ( true ) ;
234
+ AreEqual ( s , @"RequiredValue=...;BooleanValue=True;Int32Value=-1024" ) ;
235
+
236
+ var x2 = new NonBrowsableConnectionString ( s ) ;
237
+ AreEqual ( x2 . RequiredValue , "..." ) ;
238
+ AreEqual ( x2 . BooleanValue , x . BooleanValue ) ;
239
+ AreEqual ( x2 . Int32Value , x . Int32Value ) ;
240
+ AreEqual ( s , x2 . ToString ( ) ) ;
241
+ IsFalse ( x . EquivalentTo ( x2 ) ) ;
242
+ AreNotEqual ( x . ToArray ( ) , x2 . ToArray ( ) ) ;
243
+
244
+ s = x . GetBrowsableConnectionString ( false ) ;
245
+ AreEqual ( s , @"BooleanValue=True;Int32Value=-1024" ) ;
246
+
247
+ x2 = new NonBrowsableConnectionString ( s ) ;
248
+ AreEqual ( x2 . RequiredValue , null ) ;
249
+ AreEqual ( x2 . BooleanValue , x . BooleanValue ) ;
250
+ AreEqual ( x2 . Int32Value , x . Int32Value ) ;
251
+ AreEqual ( s , x2 . ToString ( ) ) ;
252
+ IsFalse ( x . EquivalentTo ( x2 ) ) ;
253
+ AreNotEqual ( x . ToArray ( ) , x2 . ToArray ( ) ) ;
254
+ }
255
+ }
256
+ }
0 commit comments