1-
2- using AwesomeAssertions ;
1+ using AwesomeAssertions ;
32using Bunit ;
3+ using System . Reflection ;
44
55namespace MudExtensions . UnitTests . Components
66{
@@ -21,5 +21,168 @@ public void MudCsvMapper_Should_Render_With_Minimal_Parameters()
2121 cut . Markup . Should ( ) . NotBeNullOrWhiteSpace ( ) ;
2222 cut . FindAll ( "input" ) . Count . Should ( ) . BeGreaterThan ( 0 ) ;
2323 }
24+
25+ [ Test ]
26+ public void MudCsvMapper_Should_Render_With_AllowCreateExpectedHeaders ( )
27+ {
28+ var cut = Context . Render < MudCsvMapper > ( parameters => parameters
29+ . Add ( p => p . AllowCreateExpectedHeaders , true )
30+ . Add ( p => p . ExpectedHeaders , new List < MudExpectedHeader > ( ) )
31+ ) ;
32+
33+ cut . Markup . Should ( ) . Contain ( "Create Header" ) ;
34+ }
35+
36+ [ Test ]
37+ public void CsvHeaders_Should_Match_ExpectedHeaders_Exactly ( )
38+ {
39+ // Arrange
40+ var expectedHeaders = new List < MudExpectedHeader >
41+ {
42+ new ( "Id" , required : true ) ,
43+ new ( "Name" , required : false )
44+ } ;
45+
46+ var cut = Context . Render < MudCsvMapper > ( p => p
47+ . Add ( x => x . ExpectedHeaders , expectedHeaders )
48+ ) ;
49+
50+ var csvContent = new List < IDictionary < string , object ? > >
51+ {
52+ new Dictionary < string , object ? >
53+ {
54+ [ "Id" ] = 1 ,
55+ [ "Name" ] = "Test"
56+ }
57+ } ;
58+
59+ cut . Instance . GetType ( )
60+ . GetField ( "CsvContent" , BindingFlags . NonPublic | BindingFlags . Instance ) !
61+ . SetValue ( cut . Instance , csvContent ) ;
62+
63+ InvokePrivate ( cut . Instance , "MatchCsvHeadersWithExpectedHeaders" ) ;
64+
65+ expectedHeaders [ 0 ] . MatchedFieldCount . Should ( ) . Be ( 1 ) ;
66+ expectedHeaders [ 1 ] . MatchedFieldCount . Should ( ) . Be ( 1 ) ;
67+ }
68+
69+ [ Test ]
70+ public void Normalize_Should_Lowercase_And_Remove_Spaces_When_Enabled ( )
71+ {
72+ var cut = Context . Render < MudCsvMapper > ( p => p
73+ . Add ( x => x . NormalizeHeaders , true )
74+ ) ;
75+
76+ var result = cut . Instance . GetType ( )
77+ . GetMethod ( "Normalize" , BindingFlags . NonPublic | BindingFlags . Instance ) !
78+ . Invoke ( cut . Instance , new object [ ] { "My Header \" Name\" " } ) ;
79+
80+ result . Should ( ) . Be ( "myheadername" ) ;
81+ }
82+
83+ [ Test ]
84+ public void AddDefaultValues_Should_Add_Confirmed_Defaults ( )
85+ {
86+ var expectedHeaders = new List < MudExpectedHeader >
87+ {
88+ new ( "Age" , required : true , allowDefaultValue : true )
89+ } ;
90+
91+ var cut = Context . Render < MudCsvMapper > ( p => p
92+ . Add ( x => x . ExpectedHeaders , expectedHeaders )
93+ ) ;
94+
95+ var csvContent = new List < IDictionary < string , object ? > >
96+ {
97+ new Dictionary < string , object ? > ( )
98+ } ;
99+
100+ SetPrivateMember ( cut . Instance , "CsvContent" , csvContent ) ;
101+
102+ var defaults = new Dictionary < string , ConfirmedDefaultValue >
103+ {
104+ [ "Age" ] = new ConfirmedDefaultValue
105+ {
106+ Confirmed = true ,
107+ DefaultValue = "18"
108+ }
109+ } ;
110+
111+ SetPrivateMember ( cut . Instance , "_defaultValueHeaders" , defaults ) ;
112+
113+ InvokePrivate ( cut . Instance , "AddDefaultValues" ) ;
114+
115+ csvContent [ 0 ] . ContainsKey ( "Age" ) . Should ( ) . BeTrue ( ) ;
116+ csvContent [ 0 ] [ "Age" ] . Should ( ) . Be ( "18" ) ;
117+ }
118+
119+
120+ [ Test ]
121+ public void RemoveUnmappedData_Should_Remove_Unmapped_Fields ( )
122+ {
123+ var cut = Context . Render < MudCsvMapper > ( ) ;
124+
125+ var headers = new List < MudCsvHeader >
126+ {
127+ new ( "A" , "File" ) ,
128+ new ( "B" , "Mapped" )
129+ } ;
130+
131+ SetPrivateMember ( cut . Instance , "MudCsvHeaders" , headers ) ;
132+
133+ var csvContent = new List < IDictionary < string , object ? > >
134+ {
135+ new Dictionary < string , object ? >
136+ {
137+ [ "A" ] = 1 ,
138+ [ "B" ] = 2
139+ }
140+ } ;
141+
142+ SetPrivateMember ( cut . Instance , "CsvContent" , csvContent ) ;
143+
144+ InvokePrivate ( cut . Instance , "RemoveUnmappedData" ) ;
145+
146+ csvContent [ 0 ] . ContainsKey ( "A" ) . Should ( ) . BeFalse ( ) ;
147+ csvContent [ 0 ] . ContainsKey ( "B" ) . Should ( ) . BeTrue ( ) ;
148+ }
149+
150+
151+
152+
153+ private static void InvokePrivate ( object instance , string methodName )
154+ {
155+ var method = instance . GetType ( )
156+ . GetMethod ( methodName , BindingFlags . NonPublic | BindingFlags . Instance ) ;
157+
158+ method . Should ( ) . NotBeNull ( ) ;
159+ method ! . Invoke ( instance , null ) ;
160+ }
161+
162+ private static void SetPrivateMember ( object instance , string name , object value )
163+ {
164+ var type = instance . GetType ( ) ;
165+
166+ var prop = type . GetProperty ( name ,
167+ BindingFlags . NonPublic | BindingFlags . Instance ) ;
168+
169+ if ( prop != null )
170+ {
171+ prop . SetValue ( instance , value ) ;
172+ return ;
173+ }
174+
175+ var field = type . GetField ( name ,
176+ BindingFlags . NonPublic | BindingFlags . Instance ) ;
177+
178+ if ( field != null )
179+ {
180+ field . SetValue ( instance , value ) ;
181+ return ;
182+ }
183+
184+ Assert . Fail ( $ "Private member '{ name } ' not found on { type . Name } ") ;
185+ }
186+
24187 }
25188}
0 commit comments