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