2008-02-04 Carlos Alberto Cortez <calberto.cortez@gmail.com>
[mono.git] / mcs / class / Managed.Windows.Forms / Test / System.Windows.Forms / CurrencyManagerTest.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2006 Novell, Inc.
21 //
22 // Authors:
23 //      Jackson Harper  jackson@ximian.com
24
25 using System;
26 using System.Collections;
27 using System.ComponentModel;
28 using System.Data;
29 using System.Reflection;
30 using System.Windows.Forms;
31
32 using NUnit.Framework;
33
34 namespace MonoTests.System.Windows.Forms.DataBinding
35 {
36         [TestFixture]
37         public class CurrencyManagerTest
38         {
39                 [Test]
40                 public void Defaults ()
41                 {
42                         BindingContext bc = new BindingContext ();
43                         ArrayList data_source = new ArrayList ();
44                         CurrencyManager cm = bc [data_source] as CurrencyManager;
45
46                         Assert.AreSame (data_source, cm.List, "DEFAULTS1");
47                         Assert.AreEqual (0, cm.Count, "DEFAULTS2");
48                         Assert.AreEqual (-1, cm.Position, "DEFAULTS3");
49                 }
50
51                 [Test]
52                 [ExpectedException (typeof (IndexOutOfRangeException))]
53                 public void UninitializedCurrent ()
54                 {
55                         BindingContext bc = new BindingContext ();
56                         ArrayList data_source = new ArrayList ();
57                         CurrencyManager cm = bc [data_source] as CurrencyManager;
58
59                         // This line should throw
60                         Assert.AreSame (null, cm.Current, "CurrentOfEmpty");
61                 }
62
63                 [Test]
64                 public void DataSetList ()
65                 {
66                         DataSet dataset = new DataSet ("DataSet");
67                         DataTable table = new DataTable ("Table");
68                         BindingContext bc = new BindingContext ();
69                         CurrencyManager cm;
70
71                         dataset.Tables.Add (table);
72                         cm = bc [dataset] as CurrencyManager;
73
74                         Assert.AreEqual (typeof (DataViewManager), cm.List.GetType (), "DATASETLIST1");
75                         Assert.AreEqual (1, cm.Count, "DATASETLIST2");
76                         Assert.AreEqual (0, cm.Position, "DATASETLIST3");
77 //                      Assert.AreEqual (typeof (DataViewManagerListItemTypeDescriptor), cm.Current.GetType (),
78 //                                      "DATASETLIST4");
79                 }
80
81                 [Test]
82                 public void DataSetListTable ()
83                 {
84                         DataSet dataset = new DataSet ("DataSet");
85                         DataTable table = new DataTable ("Table");
86                         BindingContext bc = new BindingContext ();
87                         CurrencyManager cm;
88
89                         dataset.Tables.Add (table);
90                         cm = bc [dataset, "Table"] as CurrencyManager;
91
92                         Assert.AreEqual (typeof (DataView), cm.List.GetType (), "DATASETLIST1");
93                         Assert.AreEqual (0, cm.Count, "DATASETLIST2");
94                         Assert.AreEqual (-1, cm.Position, "DATASETLIST3");
95                 }
96
97                 [Test]
98                 [ExpectedException (typeof (ArgumentException))]
99                 public void DataSetListTableBogusField ()
100                 {
101                         DataSet dataset = new DataSet ("DataSet");
102                         DataTable table = new DataTable ("Table.Column");
103                         BindingContext bc = new BindingContext ();
104                         CurrencyManager cm;
105
106                         dataset.Tables.Add (table);
107
108                         // child list can't be created
109                         cm = bc [dataset, "Table"] as CurrencyManager;
110
111                         TestHelper.RemoveWarning (cm);
112                 }
113
114                 [Test] // bug #80107
115                 public void DataView ()
116                 {
117                         DataView dv = new DataView ();
118
119                         BindingContext bc = new BindingContext ();
120                         CurrencyManager cm = bc [dv, string.Empty] as CurrencyManager;
121                         Assert.IsNotNull (cm, "#A1");
122                         Assert.AreEqual (0, cm.Count, "#A2");
123                         Assert.AreEqual (-1, cm.Position, "#A3");
124
125                         DataTable dt = new DataTable ("Testdata");
126                         dt.Columns.Add ("A");
127                         dt.Columns.Add ("B");
128                         dt.Rows.Add (new object [] { "A1", "B1" });
129                         dt.Rows.Add (new object [] { "A2", "B2" });
130                         dv.Table = dt;
131
132                         Assert.AreEqual (2, cm.Count, "#B1");
133                         Assert.AreEqual (0, cm.Position, "#B2");
134                 }
135
136                 [Test]
137                 public void MoveArrayListForward ()
138                 {
139                         ArrayList data_source = new ArrayList ();
140                         BindingContext bc = new BindingContext ();
141
142                         for (int i = 0; i < 10; i++)
143                                 data_source.Add (new object ());
144
145                         CurrencyManager cm = bc [data_source] as CurrencyManager;
146                         for (int i = 0; i < 10; i++) {
147                                 Assert.AreSame (data_source [i], cm.Current, "MOVEALF" + i);
148                                 cm.Position++;
149                         }
150
151                         cm.Position++;
152                         cm.Position++;
153
154                         Assert.AreSame (data_source [9], cm.Current, "MOVEALFEND");
155                 }
156
157                 [Test]
158                 public void MoveArrayListBackward ()
159                 {
160                         ArrayList data_source = new ArrayList ();
161                         BindingContext bc = new BindingContext ();
162
163                         for (int i = 0; i < 10; i++)
164                                 data_source.Add (new object ());
165
166                         CurrencyManager cm = bc [data_source] as CurrencyManager;
167                         cm.Position = 9;
168                         for (int i = 9; i >= 0; i--) {
169                                 Assert.AreSame (data_source [i], cm.Current, "MOVEALB" + i);
170                                 cm.Position--;
171                         }
172
173                         cm.Position--;
174                         cm.Position--;
175
176                         Assert.AreSame (data_source [0], cm.Current, "MOVEALBSTART");
177                 }
178
179                 [Test]
180                 public void SetPositionArrayList ()
181                 {
182                         ArrayList data_source = new ArrayList ();
183                         BindingContext bc = new BindingContext ();
184
185                         for (int i = 0; i < 10; i++)
186                                 data_source.Add (new object ());
187
188                         CurrencyManager cm = bc [data_source] as CurrencyManager;
189                         for (int i = 3; i >= 0; i--) {
190                                 cm.Position = i;
191                                 Assert.AreSame (data_source [i], cm.Current, "MOVEAL1-" + i);
192                         }
193
194                         cm.Position--;
195
196                         for (int i = 0; i < 10; i++) {
197                                 cm.Position = i;
198                                 Assert.AreSame (data_source [i], cm.Current, "MOVEAL2-" + i);
199                         }
200
201                         for (int i = 5; i < 10; i++) {
202                                 cm.Position = i;
203                                 Assert.AreSame (data_source [i], cm.Current, "MOVEAL3-" + i);
204                         }
205                 }
206
207                 [Test]
208                 public void LateBuildDataTable ()
209                 {
210                         DataTable data_source = new DataTable ("Table");
211                         BindingContext bc = new BindingContext ();
212                         CurrencyManager cm = bc [data_source] as CurrencyManager;
213
214                         Assert.AreEqual (-1, cm.Position, "LATEBUILDTABLE1");
215                         Assert.AreEqual (0, cm.Count, "LATEBUILDTABLE2");
216
217                         DataColumn column = new DataColumn ("Column");
218                         column.DataType = typeof (int);
219                         data_source.Columns.Add (column);
220                         
221                         for (int i = 0; i < 10; i++) {
222                                 DataRow row = data_source.NewRow ();
223                                 row ["Column"] = i;
224                                 data_source.Rows.Add (row);
225                         }
226
227                         Assert.AreEqual (0, cm.Position, "LATEBUILDTABLE3");
228                         Assert.AreEqual (10, cm.Count, "LATEBUILDTABLE4");
229                 }
230
231                 [Test]
232                 public void LateBuildArrayList ()
233                 {
234                         ArrayList data_source = new ArrayList ();
235                         BindingContext bc = new BindingContext ();
236                         CurrencyManager cm = bc [data_source] as CurrencyManager;
237
238                         Assert.AreEqual (-1, cm.Position, "LATEBUILDLIST1");
239                         Assert.AreEqual (0, cm.Count, "LATEBUILDLIST2");
240
241                         data_source.AddRange (new object [] { 1, 2, 3, 4, 5, 6, 7 });
242
243                         Assert.AreEqual (-1, cm.Position, "LATEBUILDLIST3");
244                         Assert.AreEqual (7, cm.Count, "LATEBUILDLIST4");
245                 }
246
247                 [Test]
248                 public void MoveDataTableForward ()
249                 {
250                         DataTable data_source = new DataTable ("Table");
251                         BindingContext bc = new BindingContext ();
252                         CurrencyManager cm = bc [data_source] as CurrencyManager;
253                         DataColumn column = new DataColumn ("Column");
254
255                         column.DataType = typeof (int);
256                         data_source.Columns.Add (column);
257                         for (int i = 0; i < 10; i++) {
258                                 DataRow row = data_source.NewRow ();
259                                 row ["Column"] = i;
260                                 data_source.Rows.Add (row);
261                         }
262
263
264                         for (int i = 0; i < 10; i++) {
265                                 DataRowView row = cm.Current as DataRowView;
266                                 Assert.IsFalse (row == null, "MOVETABLEF-NULL-" + i);
267                                 Assert.AreEqual (row ["Column"], i, "MOVETABLEF-" + i);
268                                 cm.Position++;
269                         }
270
271                         cm.Position++;
272                         cm.Position++;
273
274                         Assert.AreEqual (9, ((DataRowView) cm.Current) ["Column"], "MOVETABLEF-END");
275                 }
276
277                 [Test]
278                 public void MoveDataTableBackward ()
279                 {
280                         DataTable data_source = new DataTable ("Table");
281                         BindingContext bc = new BindingContext ();
282                         CurrencyManager cm = bc [data_source] as CurrencyManager;
283                         DataColumn column = new DataColumn ("Column");
284
285                         column.DataType = typeof (int);
286                         data_source.Columns.Add (column);
287                         for (int i = 0; i < 10; i++) {
288                                 DataRow row = data_source.NewRow ();
289                                 row ["Column"] = i;
290                                 data_source.Rows.Add (row);
291                         }
292
293
294                         cm.Position = 9;
295                         for (int i = 9; i >= 0; i--) {
296                                 DataRowView row = cm.Current as DataRowView;
297                                 Assert.IsFalse (row == null, "MOVETABLEB-NULL-" + i);
298                                 Assert.AreEqual (row ["Column"], i, "MOVETABLEB-" + i);
299                                 cm.Position--;
300                         }
301
302                         cm.Position--;
303                         cm.Position--;
304
305                         Assert.AreEqual (0, ((DataRowView) cm.Current) ["Column"], "MOVETABLEB-START");
306                 }
307
308                 [Test]
309                 public void SetPositionDataTable ()
310                 {
311                         DataTable data_source = new DataTable ("Table");
312                         BindingContext bc = new BindingContext ();
313                         CurrencyManager cm = bc [data_source] as CurrencyManager;
314                         DataColumn column = new DataColumn ("Column");
315
316                         column.DataType = typeof (int);
317                         data_source.Columns.Add (column);
318                         for (int i = 0; i < 10; i++) {
319                                 DataRow row = data_source.NewRow ();
320                                 row ["Column"] = i;
321                                 data_source.Rows.Add (row);
322                         }
323
324
325                         for (int i = 5; i < 10; i++) {
326                                 cm.Position = i;
327                                 DataRowView row = cm.Current as DataRowView;
328                                 Assert.IsFalse (row == null, "SETTABLE1-NULL-" + i);
329                                 Assert.AreEqual (row ["Column"], i, "SETTABLE1-" + i);
330                         }
331
332                         for (int i = 5; i >= 0; i--) {
333                                 cm.Position = i;
334                                 DataRowView row = cm.Current as DataRowView;
335                                 Assert.IsFalse (row == null, "SETTABLE2-NULL-" + i);
336                                 Assert.AreEqual (row ["Column"], i, "SETTABLE2-" + i);
337                         }
338                 }
339
340                 [Test]
341                 public void NavigateDataSetToTable ()
342                 {
343                         DataSet data_source = new DataSet ("DataSet");
344                         DataTable table = new DataTable ("Table");
345                         DataColumn column = new DataColumn ("Column");
346                         BindingContext bc = new BindingContext ();
347
348                         data_source.Tables.Add (table);
349
350                         column.DataType = typeof (int);
351                         table.Columns.Add (column);
352                         for (int i = 0; i < 10; i++) {
353                                 DataRow row = table.NewRow ();
354                                 row ["Column"] = i;
355                                 table.Rows.Add (row);
356                         }
357
358                         CurrencyManager cm = bc [data_source, "Table"] as CurrencyManager;
359
360                         Assert.AreEqual (0, cm.Position, "NAVSETTOTABLE1");
361                         Assert.AreEqual (10, cm.Count, "NAVSETTOTABLE2");
362                         Assert.AreEqual (typeof (DataView), cm.List.GetType (), "NAVSETTOTABLE3");
363
364                         for (int i = 0; i < 10; i++) {
365                                 DataRowView row = cm.Current as DataRowView;
366                                 Assert.IsFalse (row == null, "NAVSETTOTABLE-NULL-" + i);
367                                 Assert.AreEqual (i, row ["Column"], "NAVSETTOTABLE-" + i);
368                                 cm.Position++;
369                         }
370
371                         cm.Position++;
372                         cm.Position++;
373
374                         Assert.AreEqual (9, ((DataRowView) cm.Current) ["Column"], "NAVSETTOTABLE-END");
375                 }
376
377                 [Test]
378                 public void NavigateDataSetToColumn ()
379                 {
380                         DataSet data_source = new DataSet ("DataSet");
381                         DataTable table = new DataTable ("Table");
382                         DataColumn column = new DataColumn ("Column");
383                         BindingContext bc = new BindingContext ();
384
385                         data_source.Tables.Add (table);
386
387                         column.DataType = typeof (int);
388                         table.Columns.Add (column);
389                         for (int i = 0; i < 10; i++) {
390                                 DataRow row = table.NewRow ();
391                                 row ["Column"] = i;
392                                 table.Rows.Add (row);
393                         }
394
395                         CurrencyManager cm = bc [data_source, "Table.Column"] as CurrencyManager;
396
397                         Assert.AreEqual (null, cm, "NAVSETTOCOLUMN1");
398                 }
399
400                 [Test]
401                 public void NavigateDataSetToParentRelation ()
402                 {
403                         DataSet data_source = CreateRelatedDataSet ();
404                         BindingContext bc = new BindingContext ();
405                         CurrencyManager cm = bc [data_source, "Table1.Relation"] as CurrencyManager;
406
407                         Assert.AreEqual (0, cm.Position, "NAVSETTORELATION1");
408                         Assert.AreEqual (1, cm.Count, "NAVSETTORELATION2");
409                         Assert.IsTrue (cm.List is DataView, "NAVSETTORELATION3");
410
411                         DataRowView row = cm.Current as DataRowView;
412                         Assert.IsFalse (row == null, "NAVSETTORELATION-NULL-VALUE");
413                         Assert.AreEqual (0, row ["Two"], "NAVSETTORELATION-VALUE");
414
415                         cm.Position++;
416                         cm.Position++;
417
418                         Assert.AreEqual (0, ((DataRowView) cm.Current) ["Two"], "NAVSETTORELATION-END");
419                 }
420
421                 [Test]
422                 [ExpectedException (typeof (ArgumentException))]
423                 public void DataSetToChildRelation ()
424                 {
425                         DataSet data_source = CreateRelatedDataSet ();
426                         BindingContext bc = new BindingContext ();
427
428                         // Can't create a list on a child relation
429                         CurrencyManager cm = bc [data_source, "Table2.Relation"] as CurrencyManager;
430
431                         TestHelper.RemoveWarning (cm);
432                 }
433
434                 [Test]
435                 public void DataSetToParentRelationField ()
436                 {
437                         DataSet data_source = CreateRelatedDataSet ();
438                         BindingContext bc = new BindingContext ();
439
440                         CurrencyManager cm = bc [data_source, "Table1.Relation.Two"] as CurrencyManager;
441
442                         Assert.AreEqual (null, cm, "SETTOPARENTRELATIONFIELD");
443                 }
444
445                 [Test]
446                 public void MultiColumnedRelation ()
447                 {
448                         DataSet dataset = new DataSet ();
449                         DataTable sports = new DataTable ("Sports");
450                         DataTable athletes = new DataTable ("Athletes");
451                 
452                         DataColumn column;
453                         DataRow row;
454
455                         column = new DataColumn ();
456                         column.DataType = typeof (int);
457                         column.ColumnName = "SportID";
458                         column.Unique = true;
459                         sports.Columns.Add (column);
460
461                         column = new DataColumn ();
462                         column.DataType = typeof (string);
463                         column.ColumnName = "SportName";
464                         sports.Columns.Add (column);
465
466
467                         string [] sports_names = new string [] { "Hockey", "Baseball", "Basketball", "Football", "Boxing", "Surfing" };
468                         for (int i = 0; i < sports_names.Length; i++) {
469                                 row = sports.NewRow ();
470                                 row ["SportID"] = i;
471                                 row ["SportName"] = sports_names [i];
472                                 sports.Rows.Add (row);
473                         }
474                 
475                 
476                         // Athletes table
477                         column = new DataColumn ();
478                         column.DataType = typeof (int);
479                         column.ColumnName = "AthleteID";
480                         column.Unique = true;
481                         athletes.Columns.Add (column);
482
483                         column = new DataColumn ();
484                         column.DataType = typeof (int);
485                         column.ColumnName = "Sport";
486                         athletes.Columns.Add (column);
487
488                         column = new DataColumn ();
489                         column.DataType = typeof (string);
490                         column.ColumnName = "AthleteName";
491                         athletes.Columns.Add (column);
492
493                         string [] athlete_names = new string [] { "@alp", "@lupus", "@tjfontaine", "duncan", "marv", "WindowsUninstall",
494                                                                   "@jackson", "@migHome", "_Synced[work]", "GodZhila", "Raboo",
495                                                                   "@jchambers", "@mkestner", "barbosa", "IzeBurn", "squinky86",
496                                                                   "@kangaroo",  "@paco", "Demian", "logiclrd", "tenshiKur0" };
497                         for (int i = 0; i < athlete_names.Length; i++) {
498                                 row = athletes.NewRow ();
499                                 row ["AthleteID"] = i;
500                                 row ["Sport"] = i % sports_names.Length;
501                                 row ["AthleteName"] = athlete_names [i];
502                                 athletes.Rows.Add (row);
503                         }
504
505                         dataset.Tables.Add (sports);
506                         dataset.Tables.Add (athletes);
507                         dataset.Relations.Add ("AthletesSports", sports.Columns ["SportID"], athletes.Columns ["Sport"]);
508
509                         BindingContext bc = new BindingContext ();
510                         CurrencyManager cm = bc [dataset, "Sports.AthletesSports"] as CurrencyManager;
511
512                         Assert.AreEqual (0, cm.Position, "MC1");
513                         Assert.AreEqual (4, cm.Count, "MC2");
514
515                         DataRowView rowview = cm.Current as DataRowView;
516                         Assert.IsFalse (rowview == null, "MC3");
517                         Assert.AreEqual (0, rowview ["AthleteID"], "MC4");
518                         Assert.AreEqual ("@alp", rowview ["AthleteName"], "MC5");
519                         Assert.AreEqual (0, rowview ["Sport"], "MC6");
520
521                         cm.Position++;
522
523                         rowview = cm.Current as DataRowView;
524                         Assert.IsFalse (rowview == null, "MC7");
525                         Assert.AreEqual (6, rowview ["AthleteID"], "MC8");
526                         Assert.AreEqual ("@jackson", rowview ["AthleteName"], "MC9");
527                         Assert.AreEqual (0, rowview ["Sport"], "MC10");
528
529                         cm.Position++;
530
531                         rowview = cm.Current as DataRowView;
532                         Assert.IsFalse (rowview == null, "MC11");
533                         Assert.AreEqual (12, rowview ["AthleteID"], "MC12");
534                         Assert.AreEqual ("@mkestner", rowview ["AthleteName"], "MC13");
535                         Assert.AreEqual (0, rowview ["Sport"], "MC14");
536
537                         cm.Position++;
538
539                         rowview = cm.Current as DataRowView;
540                         Assert.IsFalse (rowview == null, "MC15");
541                         Assert.AreEqual (18, rowview ["AthleteID"], "MC16");
542                         Assert.AreEqual ("Demian", rowview ["AthleteName"], "MC17");
543                         Assert.AreEqual (0, rowview ["Sport"], "MC18");
544
545                         cm.Position++;
546
547                         rowview = cm.Current as DataRowView;
548                         Assert.IsFalse (rowview == null, "MC19");
549                         Assert.AreEqual (18, rowview ["AthleteID"], "MC20");
550                         Assert.AreEqual ("Demian", rowview ["AthleteName"], "MC21");
551                         Assert.AreEqual (0, rowview ["Sport"], "MC22");
552                 }
553
554                 private DataSet CreateRelatedDataSet ()
555                 {
556                         DataSet dataset = new DataSet ("DataSet");
557                         DataTable dt1 = new DataTable ("Table1");
558                         DataTable dt2 = new DataTable ("Table2");
559                         DataColumn column;
560
561                         column = new DataColumn ("One");
562                         column.DataType = typeof (int);
563                         column.Unique = true;
564                         dt1.Columns.Add (column);
565
566                         for (int i = 0; i < 10; i++) {
567                                 DataRow row = dt1.NewRow ();
568                                 row ["One"] = i;
569                                 dt1.Rows.Add (row);
570                         }
571                         
572                         column = new DataColumn ("Two");
573                         column.DataType = typeof (int);
574                         column.Unique = true;
575                         dt2.Columns.Add (column);
576
577                         for (int i = 0; i < 10; i++) {
578                                 DataRow row = dt2.NewRow ();
579                                 row ["Two"] = i;
580                                 dt2.Rows.Add (row);
581                         }
582
583                         dataset.Tables.Add (dt1);
584                         dataset.Tables.Add (dt2);
585                         dataset.Relations.Add ("Relation", dt1.Columns ["One"], dt2.Columns ["Two"]);
586
587                         return dataset;
588                 }
589                 [Test]
590                 public void EndUninitializedEdit ()
591                 {
592                         ArrayList list = new ArrayList ();
593                         BindingContext bc = new BindingContext ();
594                         CurrencyManager cm = bc [list] as CurrencyManager;
595
596                         cm.EndCurrentEdit ();
597                 }
598
599                 [Test]
600                 public void CancelUninitializedEdit ()
601                 {
602                         ArrayList list = new ArrayList ();
603                         BindingContext bc = new BindingContext ();
604                         CurrencyManager cm = bc [list] as CurrencyManager;
605
606                         cm.CancelCurrentEdit ();
607                 }
608
609                 [Test]
610                 public void CheckPositionOfRelatedSibling1 ()
611                 {
612                         DataSet data_source = CreateRelatedDataSet ();
613                         BindingContext bc = new BindingContext ();
614                         CurrencyManager cm = bc [data_source, "Table1.Relation"] as CurrencyManager;
615                         CurrencyManager scm = bc [data_source, "Table1"] as CurrencyManager;
616
617                         cm.Position++;
618                         cm.Position++;
619
620                         // position is not updated
621                         Assert.AreEqual (0, scm.Position, "#8");
622                 }
623
624                 [Test]
625                 public void CheckPositionOfRelatedSibling2 ()
626                 {
627                         DataSet data_source = CreateRelatedDataSet ();
628                         BindingContext bc = new BindingContext ();
629                         CurrencyManager cm = bc [data_source, "Table1.Relation"] as CurrencyManager;
630                         CurrencyManager scm = bc [data_source, "Table1"] as CurrencyManager;
631
632                         Assert.AreEqual (0, cm.Position, "#1");
633
634                         scm.Position++;
635
636                         Assert.AreEqual (0, cm.Position, "#2");
637                 }
638
639                 int event_num;
640                 int current_changed;
641                 int position_changed;
642                 int item_changed;
643                 int metadata_changed;
644                 string event_log = "";
645                 ItemChangedEventArgs item_changed_args;
646 #if NET_2_0
647                 bool list_changed_called;
648                 ListChangedEventArgs list_changed_args;
649 #endif
650
651                 void CurrentChanged (object sender, EventArgs args)
652                 {
653                         current_changed = ++event_num;
654                         Console.WriteLine ("current_changed = {0}", current_changed);
655                         //Console.WriteLine (Environment.StackTrace);
656                         event_log += String.Format ("{0}: CurrentChanged\n", current_changed);
657                 }
658                 void PositionChanged (object sender, EventArgs args)
659                 {
660                         position_changed = ++event_num;
661                         Console.WriteLine ("position_changed = {0}", position_changed);
662                         //Console.WriteLine (Environment.StackTrace);
663                         event_log += String.Format ("{0}: PositionChanged (to {1})\n", position_changed, ((CurrencyManager)sender).Position);
664                 }
665                 void ItemChanged (object sender, ItemChangedEventArgs args)
666                 {
667                         item_changed = ++event_num;
668                         item_changed_args = args;
669                         Console.WriteLine ("item_changed = {0}, index = {1}", item_changed, args.Index);
670                         //Console.WriteLine (Environment.StackTrace);
671                         event_log += String.Format ("{0}: ItemChanged (index = {1})\n", item_changed, args.Index);
672                 }
673                 void ListChanged (object sender, ListChangedEventArgs args)
674                 {
675                         Console.WriteLine ("ListChanged ({0},{1},{2})", args.ListChangedType, args.OldIndex, args.NewIndex);
676                         //Console.WriteLine (Environment.StackTrace);
677                         event_log += String.Format (" : ListChanged ({0}, {1}, {2})\n", args.ListChangedType, args.OldIndex, args.NewIndex);
678                 }
679                 void MetaDataChanged (object sender, EventArgs args)
680                 {
681                         metadata_changed = ++event_num;
682                         Console.WriteLine ("metadata_changed = {0}", metadata_changed);
683                         //Console.WriteLine (Environment.StackTrace);
684                         event_log += String.Format ("{0}: MetaDataChanged\n", metadata_changed);
685                 }
686 #if NET_2_0
687                 // CurrencyManager.ListChanged handler, not IBindingList.ListChanged
688                 void ListChangedEvent (object sender, ListChangedEventArgs args)
689                 {
690                         list_changed_called = true;
691                         list_changed_args = args;
692                         Console.WriteLine ("CurrencyManager.ListChanged ({0},{1},{2})", args.ListChangedType, args.OldIndex, args.NewIndex);
693
694                 }
695 #endif
696
697                 [Test]
698                 public void AddNew ()
699                 {
700                         DataSet data_source = CreateRelatedDataSet ();
701                         BindingContext bc = new BindingContext ();
702                         CurrencyManager cm = bc [data_source, "Table1"] as CurrencyManager;
703
704                         event_num = current_changed = position_changed = -1;
705                         cm.CurrentChanged += new EventHandler (CurrentChanged);
706                         cm.PositionChanged += new EventHandler (PositionChanged);
707                         cm.ItemChanged += new ItemChangedEventHandler (ItemChanged);
708 #if NET_2_0
709                         list_changed_called = false;
710                         cm.ListChanged += new ListChangedEventHandler (ListChangedEvent);
711 #endif
712
713                         Assert.AreEqual (0, cm.Position, "AddNew1");
714                         Assert.AreEqual (10, cm.Count, "AddNew2");
715                         Assert.AreEqual (cm.Count, cm.List.Count, "AddNew2.5");
716
717                         cm.AddNew ();
718
719                         Assert.AreEqual (10, cm.Position, "AddNew3");
720                         Assert.AreEqual (11, cm.Count, "AddNew4");
721                         Assert.AreEqual (cm.Count, cm.List.Count, "AddNew4.5");
722
723                         Assert.AreEqual (0, item_changed, "AddNew5");
724                         Assert.AreEqual (-1, item_changed_args.Index, "AddNew6");
725                         Assert.AreEqual (1, current_changed, "AddNew7");
726                         Assert.AreEqual (2, position_changed, "AddNew8");
727 #if NET_2_0
728                         Assert.AreEqual (true, list_changed_called, "AddNew9");
729                         Assert.AreEqual (-1, list_changed_args.OldIndex, "AddNew10");
730                         Assert.AreEqual (10, list_changed_args.NewIndex, "AddNew11");
731 #endif
732
733                         cm.CurrentChanged -= new EventHandler (CurrentChanged);
734                         cm.PositionChanged -= new EventHandler (PositionChanged);
735 #if NET_2_0
736                         cm.ListChanged -= new ListChangedEventHandler (ListChangedEvent);
737 #endif
738                 }
739
740                 [Test]
741                 public void CancelAddNew ()
742                 {
743                         if (TestHelper.RunningOnUnix) {
744                                 Assert.Ignore ("Fails at the moment");
745                         }
746
747                         DataSet data_source = CreateRelatedDataSet ();
748                         BindingContext bc = new BindingContext ();
749                         CurrencyManager cm = bc [data_source, "Table1"] as CurrencyManager;
750
751                         DataView dv = cm.List as DataView;
752
753                         event_num = current_changed = position_changed = -1;
754                         cm.CurrentChanged += new EventHandler (CurrentChanged);
755                         cm.PositionChanged += new EventHandler (PositionChanged);
756                         cm.ItemChanged += new ItemChangedEventHandler (ItemChanged);
757                         dv.ListChanged += new ListChangedEventHandler (ListChanged);
758
759                         Assert.AreEqual (0, cm.Position, "CancelAddNew1");
760                         Assert.AreEqual (10, cm.Count, "CancelAddNew2");
761                         Assert.AreEqual (cm.Count, cm.List.Count, "AddNew2.5");
762
763                         cm.AddNew ();
764
765                         Assert.AreEqual (0, item_changed, "CancelAddNew3");
766                         Assert.AreEqual (-1, item_changed_args.Index, "CancelAddNew4");
767                         Assert.AreEqual (1, current_changed, "CancelAddNew5");
768                         Assert.AreEqual (2, position_changed, "CancelAddNew6");
769
770                         cm.CancelCurrentEdit ();
771
772                         Assert.AreEqual (6, item_changed, "CancelAddNew7");
773                         Assert.AreEqual (9, item_changed_args.Index, "CancelAddNew8");
774                         Assert.AreEqual (3, current_changed, "CancelAddNew9");
775                         Assert.AreEqual (4, position_changed, "CancelAddNew10");
776
777                         Assert.AreEqual (9, cm.Position, "CancelAddNew11");
778                         Assert.AreEqual (10, cm.Count, "CancelAddNew12");
779                         Assert.AreEqual (cm.Count, cm.List.Count, "AddNew12.5");
780
781                         cm.CurrentChanged -= new EventHandler (CurrentChanged);
782                         cm.PositionChanged -= new EventHandler (PositionChanged);
783                 }
784
785                 [Test]
786                 public void EndAddNew ()
787                 {
788 #if NET_2_0
789                         if (TestHelper.RunningOnUnix) {
790                                 Assert.Ignore ("Fails with 2.0 profile");
791                         }
792 #endif
793                         DataSet data_source = CreateRelatedDataSet ();
794                         BindingContext bc = new BindingContext ();
795                         CurrencyManager cm = bc [data_source.Tables["Table1"], ""] as CurrencyManager;
796
797                         data_source.Tables["Table1"].DefaultView.ListChanged += 
798                                 new ListChangedEventHandler (DataView_ListChanged);
799
800                         event_num = current_changed = position_changed = -1;
801                         cm.CurrentChanged += new EventHandler (CurrentChanged);
802                         cm.PositionChanged += new EventHandler (PositionChanged);
803                         cm.ItemChanged += new ItemChangedEventHandler (ItemChanged);
804
805                         Assert.AreEqual (0, cm.Position, "EndAddNew1");
806                         Assert.AreEqual (10, cm.Count, "EndAddNew2");
807
808                         cm.AddNew ();
809                         Console.WriteLine ("position = {0}", cm.Position);
810
811                         Assert.AreEqual (0, item_changed, "EndAddNew3");
812                         Assert.AreEqual (-1, item_changed_args.Index, "EndAddNew4");
813                         Assert.AreEqual (1, current_changed, "EndAddNew5");
814                         Assert.AreEqual (2, position_changed, "EndAddNew6");
815
816                         cm.EndCurrentEdit ();
817                         Console.WriteLine ("position = {0}", cm.Position);
818
819                         Assert.AreEqual (3, item_changed, "EndAddNew7");
820                         Assert.AreEqual (-1, item_changed_args.Index, "EndAddNew8");
821                         Assert.AreEqual (1, current_changed, "EndAddNew9");
822                         Assert.AreEqual (2, position_changed, "EndAddNew10");
823
824                         Assert.AreEqual (10, cm.Position, "EndAddNew11");
825                         Assert.AreEqual (11, cm.Count, "EndAddNew12");
826
827                         cm.CurrentChanged -= new EventHandler (CurrentChanged);
828                         cm.PositionChanged -= new EventHandler (PositionChanged);
829                 }
830
831                 void DataView_ListChanged (object sender, ListChangedEventArgs e)
832                 {
833                         Console.WriteLine ("{0} {1} {2}", e.ListChangedType, e.OldIndex, e.NewIndex);
834                 }
835
836                 [Test]
837                 public void AddNew2 ()
838                 {
839                         if (TestHelper.RunningOnUnix) {
840                                 Assert.Ignore ("Fails at the moment due to a System.Data constraint violation");
841                         }
842
843                         DataSet data_source = CreateRelatedDataSet ();
844                         BindingContext bc = new BindingContext ();
845                         CurrencyManager cm = bc [data_source, "Table1"] as CurrencyManager;
846
847                         DataView dv = cm.List as DataView;
848
849                         event_num = current_changed = position_changed = -1;
850                         cm.CurrentChanged += new EventHandler (CurrentChanged);
851                         cm.PositionChanged += new EventHandler (PositionChanged);
852                         cm.ItemChanged += new ItemChangedEventHandler (ItemChanged);
853                         dv.ListChanged += new ListChangedEventHandler (ListChanged);
854
855                         Assert.AreEqual (0, cm.Position, "AddNew1");
856                         Assert.AreEqual (10, cm.Count, "AddNew2");
857
858                         cm.AddNew ();
859
860                         Assert.AreEqual (10, cm.Position, "AddNew3");
861                         Assert.AreEqual (11, cm.Count, "AddNew4");
862
863                         // this does an implicit EndCurrentEdit
864                         cm.AddNew ();
865
866                         Assert.AreEqual (11, cm.Position, "AddNew5");
867                         Assert.AreEqual (12, cm.Count, "AddNew6");
868                 }
869
870
871                 DataSet CreateRelatedDataSetLarge ()
872                 {
873                         DataSet dataset = new DataSet ("CustomerSet");
874                         DataTable dt1 = new DataTable ("Customers");
875                         DataTable dt2 = new DataTable ("Orders");
876                         DataTable dt3 = new DataTable ("Addresses");
877                         DataColumn column;
878
879                         // customer table
880                         column = new DataColumn ("CustomerID");
881                         column.DataType = typeof (int);
882                         column.Unique = true;
883                         dt1.Columns.Add (column);
884
885                         column = new DataColumn ("CustomerName");
886                         column.DataType = typeof (string);
887                         column.Unique = false;
888                         dt1.Columns.Add (column);
889
890                         // order table
891                         column = new DataColumn ("OrderID");
892                         column.DataType = typeof (int);
893                         column.Unique = true;
894                         dt2.Columns.Add (column);
895
896                         column = new DataColumn ("ItemName");
897                         column.DataType = typeof (string);
898                         column.Unique = false;
899                         dt2.Columns.Add (column);
900
901                         column = new DataColumn ("CustomerID");
902                         column.DataType = typeof (int);
903                         column.Unique = false;
904                         dt2.Columns.Add (column);
905
906                         column = new DataColumn ("AddressID");
907                         column.DataType = typeof (int);
908                         column.Unique = false;
909                         dt2.Columns.Add (column);
910
911                         // address table
912                         column = new DataColumn ("AddressID");
913                         column.DataType = typeof (int);
914                         column.Unique = true;
915                         dt3.Columns.Add (column);
916
917                         column = new DataColumn ("AddressString");
918                         column.DataType = typeof (string);
919                         column.Unique = false;
920                         dt3.Columns.Add (column);
921
922                         column = new DataColumn ("CustomerID");
923                         column.DataType = typeof (int);
924                         column.Unique = false;
925                         dt3.Columns.Add (column);
926
927                         for (int i = 0; i < 10; i ++) {
928                                 DataRow row = dt1.NewRow ();
929                                 row["CustomerID"] = i;
930                                 row["CustomerName"] = String.Format ("Customer Name #{0}", i);
931                                 dt1.Rows.Add (row);
932                         }
933
934                         int ordernum = 0;
935                         for (int i = 0; i < 10; i ++) {
936                                 for (int j = 0; j < (i < 5 ? 3 : 5); j ++) {
937                                         DataRow row = dt2.NewRow ();
938                                         row["OrderID"] = ordernum++;
939                                         row["ItemName"] = String.Format ("Item order #{0}", j);
940                                         row["CustomerID"] = i;
941                                         row["AddressID"] = j;
942                                         dt2.Rows.Add (row);
943                                 }
944                         }
945
946                         int addressid = 0;
947                         for (int i = 0; i < 4; i ++) {
948                                 for (int j = 0; j < 4; j ++) {
949                                         DataRow row = dt3.NewRow ();
950                                         row["AddressID"] = addressid++;
951                                         row["AddressString"] = String.Format ("Customer Address {0}", j);
952                                         row["CustomerID"] = i;
953                                         dt3.Rows.Add (row);
954                                 }
955                         }
956
957                         dataset.Tables.Add (dt1);
958                         dataset.Tables.Add (dt2);
959                         dataset.Tables.Add (dt3);
960                         dataset.Relations.Add ("Customer_Orders", dt1.Columns["CustomerID"], dt2.Columns["CustomerID"]);
961                         dataset.Relations.Add ("Customer_Addresses", dt1.Columns["CustomerID"], dt3.Columns["CustomerID"]);
962                         dataset.Relations.Add ("Address_Orders", dt3.Columns["AddressID"], dt2.Columns["AddressID"]);
963
964                         return dataset;
965                 }
966
967                 [Test]
968                 public void RelatedCurrencyManagerTest ()
969                 {
970                         DataSet data_source = CreateRelatedDataSetLarge ();
971                         BindingContext bc = new BindingContext ();
972                         CurrencyManager cm = bc [data_source, "Customers"] as CurrencyManager;
973                         CurrencyManager rcm = bc [data_source, "Customers.Customer_Orders"] as CurrencyManager;
974
975                         IList list = rcm.List;
976                         Assert.AreEqual (3, rcm.Count, "count1");
977                         Assert.AreEqual (3, list.Count, "listcount1");
978
979                         cm.Position = 1;
980                         Assert.AreEqual (3, rcm.Count, "count2");
981                         Assert.AreEqual (3, list.Count, "listcount2");
982
983                         cm.Position = 5;
984                         Assert.AreEqual (5, rcm.Count, "count3");
985                         Assert.AreEqual (3, list.Count, "listcount3");
986                 }
987                 
988                 [Test]
989                 public void TestCurrencyManagerBindings ()
990                 {
991                         DataSet data_source = CreateRelatedDataSetLarge ();
992                         BindingContext bc = new BindingContext ();
993
994                         CurrencyManager cm = bc [data_source] as CurrencyManager;
995
996                         Console.WriteLine ("cm properties:");
997                         foreach (PropertyDescriptor pd in cm.GetItemProperties ())
998                                 Console.WriteLine (" + {0}", pd.Name);
999                         Console.WriteLine ();
1000
1001                         Console.WriteLine ("dataset:");
1002                         Console.WriteLine ("cm = {0}", cm.GetType());
1003                         Console.WriteLine ("cm.Count = {0}", cm.Count);
1004                         cm.Position = 0;
1005                         Console.WriteLine ("cm.Current = {0}", cm.Current);
1006                         Console.WriteLine ("cm.Current properties");
1007                         foreach (PropertyDescriptor pd in ((ICustomTypeDescriptor)cm.Current).GetProperties ())
1008                                 Console.WriteLine (" + {0}", pd.Name);
1009                         Console.WriteLine ();
1010
1011                         cm = bc [data_source.Tables["Customers"]] as CurrencyManager;
1012                         Console.WriteLine ("datatable:");
1013                         Console.WriteLine ("cm = {0}", cm.GetType());
1014                         Console.WriteLine ("cm.Count = {0}", cm.Count);
1015                         cm.Position = 0;
1016                         Console.WriteLine ("cm.Current = {0}", cm.Current);
1017                         Console.WriteLine ("cm.Current properties");
1018                         foreach (PropertyDescriptor pd in ((ICustomTypeDescriptor)cm.Current).GetProperties ())
1019                                 Console.WriteLine (" + {0}", pd.Name);
1020
1021                         Console.WriteLine ();
1022
1023                         DataViewManager vm = new DataViewManager (data_source);
1024                         Console.WriteLine ("vm properties:");
1025                         foreach (PropertyDescriptor pd in ((ITypedList)vm).GetItemProperties (null))
1026                                 Console.WriteLine (" + {0}", pd.Name);
1027                         Console.WriteLine ();
1028
1029                 }
1030
1031                 Type GetFinalType (CurrencyManager cm)
1032                 {
1033                         FieldInfo fi = cm.GetType().GetField ("finalType", BindingFlags.NonPublic | BindingFlags.Instance);
1034
1035                         return (Type)fi.GetValue (cm);
1036                 }
1037
1038                 [Test]
1039                 public void FinalTypeTest ()
1040                 {
1041                         BindingContext bc = new BindingContext ();
1042                         CurrencyManager cm;
1043                         ArrayList al;
1044                         DataSet data_source = CreateRelatedDataSetLarge ();
1045
1046                         /* empty arraylist */
1047                         al = new ArrayList ();
1048                         cm = bc[al] as CurrencyManager;
1049                         Assert.AreEqual (typeof (ArrayList), GetFinalType (cm), "A1");
1050
1051                         /* arraylist with a string element*/
1052                         al = new ArrayList ();
1053                         al.Add ("hi");
1054                         cm = bc[al] as CurrencyManager;
1055                         Assert.AreEqual (typeof (ArrayList), GetFinalType (cm), "A2");
1056
1057                         /* string array */
1058                         string[] s = new string[1];
1059                         s[0] = "hi";
1060                         cm = bc[s] as CurrencyManager;
1061                         Assert.AreEqual (typeof (string[]), GetFinalType (cm), "A3");
1062
1063                         /* dataview */
1064                         cm = bc [data_source, "Customers"] as CurrencyManager;
1065                         Assert.AreEqual (typeof (DataView), GetFinalType (cm), "A4");
1066
1067                         /* relatedview */
1068                         cm = bc [data_source, "Customers.Customer_Orders"] as CurrencyManager;
1069                         /* on MS this is a RelatedView, on Mono a RelatedDataView.  both subclass from DataView, so let's check that. */
1070                         Assert.IsFalse (typeof (DataView) == GetFinalType (cm), "A5");
1071                         Assert.IsTrue (typeof (DataView).IsAssignableFrom (GetFinalType (cm)), "A6");
1072                 }
1073
1074 #if NET_2_0
1075                 [Test]
1076                 public void ListChangedEventTest ()
1077                 {
1078                         Control c = new Control ();
1079                         c.BindingContext = new BindingContext ();
1080                         c.CreateControl ();
1081
1082                         BindingListChild<MockItem> binding_list = new BindingListChild<MockItem> ();
1083                         CurrencyManager currency_manager = (CurrencyManager)c.BindingContext [binding_list];
1084                         currency_manager.ListChanged += new ListChangedEventHandler(ListChangedEvent);
1085
1086                         ClearListChangedLog ();
1087
1088                         MockItem item = binding_list.AddNew ();
1089                         binding_list.EndNew (binding_list.IndexOf (item));
1090                         Assert.IsTrue (list_changed_called, "#A1");
1091                         Assert.AreEqual (ListChangedType.ItemAdded, list_changed_args.ListChangedType, "#A2");
1092
1093                         ClearListChangedLog ();
1094
1095                         binding_list.Insert (0, new MockItem ());
1096                         Assert.IsTrue (list_changed_called, "#B1");
1097                         Assert.AreEqual (ListChangedType.ItemAdded, list_changed_args.ListChangedType, "#B2");
1098
1099                         ClearListChangedLog ();
1100
1101                         binding_list.RemoveAt (0);
1102                         Assert.IsTrue (list_changed_called, "#D1");
1103                         Assert.AreEqual (ListChangedType.ItemDeleted, list_changed_args.ListChangedType, "#D2");
1104
1105                         ClearListChangedLog ();
1106
1107                         binding_list [0] = new MockItem ();
1108                         Assert.IsTrue (list_changed_called, "#E1");
1109                         Assert.AreEqual (ListChangedType.ItemChanged, list_changed_args.ListChangedType, "#E2");
1110
1111                         ClearListChangedLog ();
1112
1113                         binding_list.DoResetItem (0);
1114                         Assert.IsTrue (list_changed_called, "#F1");
1115                         Assert.AreEqual (ListChangedType.ItemChanged, list_changed_args.ListChangedType, "#F2");
1116
1117                         ClearListChangedLog ();
1118
1119                         binding_list.DoResetBinding ();
1120                         Assert.IsTrue (list_changed_called, "#G1");
1121                         Assert.AreEqual (ListChangedType.Reset, list_changed_args.ListChangedType, "#G2");
1122
1123                         binding_list.Clear ();
1124                         Assert.IsTrue (list_changed_called, "#F1");
1125                         Assert.AreEqual (ListChangedType.Reset, list_changed_args.ListChangedType, "#F2");
1126
1127                         currency_manager.ListChanged -= ListChangedEvent;
1128                 }
1129
1130                 void ClearListChangedLog ()
1131                 {
1132                         list_changed_called = false;
1133                         list_changed_args = null;
1134                 }
1135
1136                 public class BindingListChild<T> : BindingList<T>
1137                 {
1138                         public void DoResetItem (int position)
1139                         {
1140                                 ResetItem (position);
1141                         }
1142
1143                         public void DoResetBinding ()
1144                         {
1145                                 ResetBindings ();
1146                         }
1147                 }
1148 #endif
1149
1150         }
1151 }