1 {
2 *****************************************************************************
3 See the file COPYING.modifiedLGPL.txt, included in this distribution,
4 for details about the license.
5 *****************************************************************************
6
7 Authors: Alexander Klenin
8
9 }
10
11 unit SourcesTest;
12
13 {$mode objfpc}{$H+}{$R+}
14
15 interface
16
17 uses
18 Classes, SysUtils, FPCUnit, TestRegistry,
19 TAChartUtils, TACustomSource, TAIntervalSources, TASources;
20
21 type
22
23 { TListSourceTest }
24
25 TListSourceTest = class(TTestCase)
26 private
27 FSource: TListChartSource;
28
29 procedure AssertItemEquals(
30 const AItem: TChartDataItem; AX, AY: Double; AText: String = '';
31 AColor: TChartColor = clTAColor);
Comparenull32 function Compare(AItem1, AItem2: Pointer): Integer;
33 protected
34 procedure SetUp; override;
35 procedure TearDown; override;
36 published
37 procedure Basic;
38 procedure Bounds;
39 procedure Cache;
40 procedure DataPoint;
41 procedure DataPointSeparator;
42 procedure Enum;
43 procedure Extent;
44 procedure Multi;
45 procedure Sort;
46 end;
47
48 { TRandomSourceTest }
49
50 TRandomSourceTest = class(TTestCase)
51 published
52 procedure Extent;
53 end;
54
55 { TCalculatedSourceTest }
56
57 TCalculatedSourceTest = class(TTestCase)
58 private
59 FOrigin: TListChartSource;
60 FSource: TCalculatedChartSource;
61 protected
62 procedure SetUp; override;
63 procedure TearDown; override;
64 published
65 procedure Accumulate;
66 procedure Derivative;
67 procedure Percentage;
68 procedure Reorder;
69 end;
70
71 TIntervalSourceTest = class(TTestCase)
72 private
73 procedure AssertValueEquals(
74 const AExpected: array of Double; const AActual: TChartValueTextArray);
75 published
76 procedure IntervalSource;
77 procedure ListSource;
78 end;
79
80 implementation
81
82 uses
83 Math, TAMath, AssertHelpers;
84
85 type
86 TDummyTransform = object
87 public
IdentityDoublenull88 function IdentityDouble(AX: Double): Double;
IdentityIntegernull89 function IdentityInteger(AX: Integer): Integer;
PrepareValuesInRangeParamsnull90 function PrepareValuesInRangeParams: TValuesInRangeParams;
Roundnull91 function Round(AX: Double): Integer;
92 end;
93
94 var
95 VDummyTransform: TDummyTransform;
96
97 { TDummyTransform }
98
TDummyTransform.IdentityDoublenull99 function TDummyTransform.IdentityDouble(AX: Double): Double;
100 begin
101 Result := AX;
102 end;
103
IdentityIntegernull104 function TDummyTransform.IdentityInteger(AX: Integer): Integer;
105 begin
106 Result := AX;
107 end;
108
PrepareValuesInRangeParamsnull109 function TDummyTransform.PrepareValuesInRangeParams: TValuesInRangeParams;
110 begin
111 with Result do begin
112 FAxisToGraph := @IdentityDouble;
113 FGraphToAxis := @IdentityDouble;
114 FFormat := '';
115 FGraphToImage := @Round;
116 FMin := 30;
117 FMax := 69;
118 FMinStep := 0;
119 FScale := @IdentityInteger;
120 FUseY := false;
121 FIntervals := TChartAxisIntervalParams.Create(nil);
122 end;
123 end;
124
TDummyTransform.Roundnull125 function TDummyTransform.Round(AX: Double): Integer;
126 begin
127 Result := System.Round(AX);
128 end;
129
130 { TCalculatedSourceTest }
131
132 procedure TCalculatedSourceTest.Accumulate;
133 var
134 i, j: Integer;
135 rng: TMWCRandomGenerator;
136 begin
137 FSource.AccumulationMethod := camSum;
138 FSource.AccumulationRange := 2;
139 AssertEquals(3, FSource.YCount);
140 AssertEquals(1, FSource[0]^.X);
141 AssertEquals(102, FSource[0]^.Y);
142 AssertEquals(2, FSource[1]^.X);
143 AssertEquals(102 + 202, FSource[1]^.Y);
144 AssertEquals(202 + 302, FSource[2]^.Y);
145 FSource.AccumulationDirection := cadForward;
146 AssertEquals(202 + 302, FSource[1]^.Y);
147 AssertEquals(302 + 402, FSource[2]^.Y);
148 FSource.AccumulationDirection := cadBackward;
149 FSource.AccumulationMethod := camAverage;
150 AssertEquals((2002 + 2102) / 2, FSource[20]^.Y);
151 AssertEquals(1, FSource[0]^.X);
152 AssertEquals(102, FSource[0]^.Y);
153 AssertEquals((102 + 202) / 2, FSource[1]^.Y);
154 AssertEquals(102, FSource[0]^.Y);
155 FSource.AccumulationDirection := cadCenter;
156 AssertEquals((1102 + 1202 + 1302) / 3, FSource[11]^.Y);
157 FSource.AccumulationDirection := cadBackward;
158
159 FSource.AccumulationRange := 5;
160 rng := TMWCRandomGenerator.Create;
161 try
162 rng.Seed := 89237634;
163 for i := 1 to 100 do begin
164 j := rng.GetInRange(5, FSource.Count - 1);
165 AssertEquals(IntToStr(j), (j - 1) * 100 + 2, FSource[j]^.Y);
166 end;
167 FSource.AccumulationRange := 0;
168 FSource.AccumulationMethod := camSum;
169 rng.Seed := 23784538;
170 for i := 1 to 20 do begin
171 j := rng.GetInRange(0, FSource.Count - 1);
172 AssertEquals(
173 IntToStr(j), (j + 1) * (j + 2) * 50 + (j + 1) * 3, FSource[j]^.YList[0]);
174 end;
175 finally
176 rng.Free;
177 end;
178 end;
179
180 procedure TCalculatedSourceTest.Derivative;
181 begin
182 FSource.AccumulationMethod := camDerivative;
183 FSource.AccumulationRange := 2;
184 FOrigin.SetYValue(1, 202);
185 AssertTrue(IsNan(FSource[0]^.Y));
186 AssertEquals(100, FSource[1]^.Y);
187 FSource.AccumulationDirection := cadCenter;
188 AssertEquals(100, FSource[0]^.Y);
189 end;
190
191 procedure TCalculatedSourceTest.Percentage;
192 begin
193 FSource.Percentage := true;
194 AssertEquals(3, FSource.YCount);
195 AssertEquals(102 / (102 + 103 + 104) * 100, FSource[0]^.Y);
196 AssertEquals(103 / (102 + 103 + 104) * 100, FSource[0]^.YList[0]);
197 end;
198
199 procedure TCalculatedSourceTest.Reorder;
200 var
201 i: Integer;
202 begin
203 AssertEquals(3, FSource.YCount);
204 FSource.ReorderYList := '2';
205 AssertEquals(1, FSource.YCount);
206 AssertEquals(104, FSource[0]^.Y);
207 AssertEquals(204, FSource[1]^.Y);
208 FSource.ReorderYList := '0,2';
209 AssertEquals(2, FSource.YCount);
210 AssertEquals(102, FSource[0]^.Y);
211 AssertEquals(104, FSource[0]^.YList[0]);
212 AssertEquals(202, FSource[1]^.Y);
213 AssertEquals(204, FSource[1]^.YList[0]);
214 FSource.ReorderYList := '1,1,1';
215 AssertEquals(3, FSource.YCount);
216 AssertEquals(103, FSource[0]^.Y);
217 AssertEquals([103, 103], FSource[0]^.YList);
218 FSource.ReorderYList := '';
219 for i := 0 to FSource.Count - 1 do begin
220 AssertEquals(FOrigin[i]^.Y, FSource[i]^.Y);
221 AssertEquals(FOrigin[i]^.YList, FSource[i]^.YList);
222 end;
223 end;
224
225 procedure TCalculatedSourceTest.SetUp;
226 var
227 i: Integer;
228 begin
229 inherited SetUp;
230 FOrigin := TListChartSource.Create(nil);
231 FSource := TCalculatedChartSource.Create(nil);
232 FSource.Origin := FOrigin;
233 FOrigin.YCount := 3;
234 for i := 1 to 100 do
235 FOrigin.SetYList(FOrigin.Add(i, i * 100 + 2), [i * 100 + 3, i * 100 + 4]);
236 end;
237
238 procedure TCalculatedSourceTest.TearDown;
239 begin
240 FreeAndNil(FSource);
241 FreeAndNil(FOrigin);
242 inherited TearDown;
243 end;
244
245 { TListSourceTest }
246
247 procedure TListSourceTest.AssertItemEquals(
248 const AItem: TChartDataItem; AX, AY: Double; AText: String;
249 AColor: TChartColor);
250 begin
251 AssertEquals('X', AX, AItem.X);
252 AssertEquals('Y', AY, AItem.Y);
253 AssertEquals('Text', AText, AItem.Text);
254 AssertEquals('Color', AColor, AItem.Color);
255 end;
256
257 procedure TListSourceTest.Basic;
258 var
259 i: Integer;
260 srcDest: TListChartSource;
261 begin
262 FSource.Clear;
263 AssertEquals(0, FSource.Count);
264 AssertEquals(0, FSource.Add(1, 2, 'text', $FFFFFF));
265 AssertEquals(1, FSource.Count);
266 FSource.Delete(0);
267 AssertEquals(0, FSource.Count);
268 for i := 1 to 10 do
269 FSource.Add(i, i * 2, IntToStr(i));
270 srcDest := TListChartSource.Create(nil);
271 try
272 srcDest.CopyFrom(FSource);
273 AssertEquals(FSource.Count, srcDest.Count);
274 for i := 0 to FSource.Count - 1 do
275 with FSource[i]^ do
276 AssertItemEquals(srcDest[i]^, X, Y, Text, Color);
277 finally
278 srcDest.Free;
279 end;
280 end;
281
282 procedure TListSourceTest.Bounds;
283
284 procedure Check2(AExpectedLB, AExpectedUB: Integer; AXMin, AXMax: Double);
285 var
286 lb, ub: Integer;
287 begin
288 FSource.FindBounds(AXMin, AXMax, lb, ub);
289 AssertEquals(AExpectedLB, lb);
290 AssertEquals(AExpectedUB, ub);
291 end;
292
293 procedure Check(AExpectedLB, AExpectedUB: Integer; AValue: Double);
294 begin
295 Check2(AExpectedLB, AExpectedUB, AValue, AValue)
296 end;
297
298 procedure CheckAll;
299 begin
300 Check2(1, 2, 2, 3);
301 Check2(1, 2, 1.9, 3.1);
302 Check2(2, 1, 2.1, 2.9);
303 Check(1, 1, 2);
304 Check(1, 0, 1.9);
305 Check(0, -1, 0.9); // below left-most point
306 Check(5, 4, 5.1); // above right-most point
307 Check(4, 3, 4.9); // just below right-most point
308 Check2(2, 4, 3, 1e100);
309 Check2(0, 1, -1e100, 2);
310 end;
311
312 procedure CheckAll_XCount0;
313 begin
314 Check2(2, 3, 2, 3);
315 Check2(2, 3, 1.9, 3.1);
316 Check2(3, 2, 2.1, 2.9);
317 Check(2, 2, 2);
318 Check(2, 1, 1.9);
319 Check(0, -1, -0.1); // below left-most point
320 Check(5, 4, 4.1); // above right-most point
321 Check(4, 3, 3.9); // just below right-most point
322 Check2(2, 4, 2, 1e100);
323 Check2(0, 1, -1e100, 1);
324 end;
325
326 begin
327 FSource.Clear;
328 FSource.Add(1, 2);
329 FSource.Add(2, 3);
330 FSource.Add(3, 4);
331 FSource.Add(4, 5);
332 FSource.Add(5, 6);
333 FSource.Sorted := true;
334 CheckAll;
335 FSource.Sorted := false;
336 CheckAll;
337
338 FSource.XCount := 0;
339 CheckAll_XCount0;
340
341 FSource.XCount := 1;
342 FSource.SetXValue(1, SafeNan);
343 Check(2, 0, 2);
344 FSource.SetXValue(0, SafeNan);
345 Check2(2, 2, -1e100, 3);
346 Check2(2, 2, NegInfinity, 3);
347 end;
348
349 procedure TListSourceTest.Cache;
350 begin
351 FSource.Clear;
352 FSource.Add(5, 6);
353 FSource.Add(7, 8);
354 AssertEquals(14, FSource.ValuesTotal);
355 FSource.Add(8, SafeNan);
356 AssertEquals(14, FSource.ValuesTotal);
357 FSource.Delete(2);
358 AssertEquals(14, FSource.ValuesTotal);
359 FSource.Delete(1);
360 AssertEquals(6, FSource.ValuesTotal);
361 FSource.SetYValue(0, SafeNan);
362 AssertEquals(0, FSource.ValuesTotal);
363 FSource.SetYValue(0, 5);
364 AssertEquals(5, FSource.ValuesTotal);
365
366 FSource.Clear;
367 AssertEquals(0, FSource.ValuesTotal);
368 FSource.Add(NaN, NaN);
369 FSource.BeginUpdate;
370 FSource.EndUpdate;
371 AssertEquals(0, FSource.ValuesTotal);
372 end;
373
374 procedure TListSourceTest.DataPoint;
375 begin
376 FSource.Clear;
377 FSource.DataPoints.Add('3|4|?|text1');
378 FSource.DataPoints.Add('5|6|$FF0000|');
379 AssertEquals(2, FSource.Count);
380 AssertItemEquals(FSource[0]^, 3, 4, 'text1');
381 AssertItemEquals(FSource[1]^, 5, 6, '', $FF0000);
382 FSource[0]^.Color := 0;
383 AssertEquals('3|4|$000000|text1', FSource.DataPoints[0]);
384 FSource.DataPoints.Add('7|8|0|two words');
385 AssertEquals('two words', FSource[2]^.Text);
386 end;
387
388 procedure TListSourceTest.DataPointSeparator;
389 var
390 oldSeparator: Char;
391 begin
392 FSource.Clear;
393 oldSeparator := DefaultFormatSettings.DecimalSeparator;
394 try
395 DefaultFormatSettings.DecimalSeparator := ':';
396 FSource.DataPoints.Add('3:5|?|?|');
397 AssertEquals(3.5, FSource[0]^.X);
398 FSource.DataPoints[0] := '4.5|?|?|';
399 AssertEquals(4.5, FSource[0]^.X);
400 finally
401 DefaultFormatSettings.DecimalSeparator := oldSeparator;
402 end;
403 end;
404
405 procedure TListSourceTest.Enum;
406 var
407 it: PChartDataItem;
408 s: Double = 0;
409 begin
410 FSource.Clear;
411 for it in FSource do
412 s += 1;
413 AssertEquals(0, s);
414 FSource.Add(10, 1);
415 FSource.Add(20, 7);
416 for it in FSource do
417 s += it^.X + it^.Y;
418 AssertEquals(38, s);
419 end;
420
421 procedure TListSourceTest.Extent;
422
423 procedure AssertExtent(AX1, AY1, AX2, AY2: Double);
424 begin
425 with FSource.Extent do begin
426 AssertEquals('X1', AX1, a.X);
427 AssertEquals('Y1', AY1, a.Y);
428 AssertEquals('X2', AX2, b.X);
429 AssertEquals('Y2', AY2, b.Y);
430 end;
431 end;
432
433 begin
434 FSource.Clear;
435 Assert(IsInfinite(FSource.Extent.a.X) and IsInfinite(FSource.Extent.a.Y));
436 Assert(IsInfinite(FSource.Extent.b.X) and IsInfinite(FSource.Extent.b.Y));
437
438 FSource.Add(1, 2);
439 AssertExtent(1, 2, 1, 2);
440
441 FSource.Add(3, 4);
442 AssertExtent(1, 2, 3, 4);
443
444 FSource.SetXValue(0, -1);
445 AssertExtent(-1, 2, 3, 4);
446
447 FSource.SetXValue(1, -2);
448 AssertExtent(-2, 2, -1, 4);
449
450 FSource.SetXValue(1, SafeNaN);
451 AssertExtent(-1, 2, -1, 4);
452 FSource.SetXValue(1, -2);
453
454 FSource.SetYValue(0, 5);
455 AssertExtent(-2, 4, -1, 5);
456
457 FSource.SetYValue(0, 4.5);
458 AssertExtent(-2, 4, -1, 4.5);
459
460 FSource.SetYValue(1, SafeNaN);
461 AssertExtent(-2, 4.5, -1, 4.5);
462
463 FSource.Delete(1);
464 AssertExtent(-1, 4.5, -1, 4.5);
465
466 FSource.Clear;
467 FSource.Add(1, 1);
468 FSource.Add(2, 2);
469 FSource.Add(3, 3);
470 FSource.Add(4, 4);
471 FSource.Delete(0);
472 FSource.Delete(1);
473 AssertExtent(2, 2, 4, 4);
474 end;
475
476 procedure TListSourceTest.Multi;
477 begin
478 FSource.Clear;
479 AssertEquals(1, FSource.YCount);
480 AssertEquals(1, FSource.YCount);
481
482 FSource.Add(1, 2);
483 FSource.YCount := 2;
484 AssertEquals([0], FSource[0]^.YList);
485
486 FSource.SetYList(0, [3]);
487 AssertEquals(3, FSource[0]^.YList[0]);
488
489 FSource.DataPoints.Add('1|2|3|?|t');
490 AssertEquals(1, FSource.XCount);
491 AssertEquals(2, FSource.YCount);
492 AssertEquals(1, FSource[1]^.X);
493 AssertEquals(2, FSource[1]^.Y);
494 AssertEquals(3, FSource[1]^.YList[0]);
495
496 // Check too many parts
497 try
498 FSource.DataPoints.Add('10|20|30|40|?|');
499 except
500 on E: Exception do
501 AssertTrue('Too many values', E is EListSourceStringError);
502 end;
503 AssertEquals(2, FSource.Count);
504
505 // Check too few parts
506 try
507 FSource.DataPoints.Add('10|20|?|');
508 except
509 on E: Exception do
510 AssertTrue('Too few values', E is EListSourceStringError);
511 end;
512 AssertEquals(2, FSource.Count);
513
514 // Check text part missing
515 try
516 FSource.DataPoints.Add('10|20|30|?');
517 except
518 on E: Exception do
519 AssertTrue('Text field missing', E is EListSourceStringError);
520 end;
521 AssertEquals(2, FSource.Count);
522
523 // Check color part missing
524 try
525 FSource.DataPoints.Add('10|20|30|t');
526 except
527 on E: Exception do
528 AssertTrue('Color field missing', E is EListSourceStringError);
529 end;
530 AssertEquals(2, FSource.Count);
531
532 // Check non-numeric parts
533 try
534 FSource.DataPoints.Add('abc|20|30|?|t');
535 except
536 on E: Exception do
537 AssertTrue('Non-numeric X', E is EListSourceStringError);
538 end;
539 try
540 FSource.DataPoints.Add('10|abc|30|?|t');
541 except
542 on E: Exception do
543 AssertTrue('Non-numeric Y', E is EListSourceStringError);
544 end;
545 try
546 FSource.DataPoints.Add('10|20|abc|?|t');
547 except
548 on E: Exception do
549 AssertTrue('Non-numeric YList', E is EListSourceStringError);
550 end;
551 try
552 FSource.DataPoints.Add('10|20|30|abc|t');
553 except
554 on E: Exception do
555 AssertTrue('Non-numeric Color', E is EListSourceStringError);
556 end;
557
558 // check empty list
559 try
560 FSource.AddXYList(4, []);
561 except
562 on E: Exception do
563 AssertTrue('Empty YList', E is TListChartSource.EYListEmptyError);
564 end;
565 AssertEquals(2, FSource.Count);
566
567 // Check decimal separators
568 FSource.DataPoints.Add('1.23|2.34|3|?|t');
569 AssertEquals(1.23, FSource[2]^.X);
570 AssertEquals(2.34, FSource[2]^.Y);
571
572 FSource.DataPoints.Add('1,23|2,34|3|?|t');
573 AssertEquals(1.23, FSource[3]^.X);
574 AssertEquals(2.34, FSource[3]^.Y);
575
576 // Check missing values
577 FSource.DataPoints.Add('|2|3|?|t');
578 AssertTrue('IsNaN', IsNaN(FSource[4]^.X));
579 AssertEquals(2, FSource[4]^.Y);
580 AssertEquals(3, FSource[4]^.YList[0]);
581
582 FSource.DataPoints.Add('1||3|?|t');
583 AssertEquals(1, FSource[5]^.X);
584 AssertTrue('IsNaN', IsNaN(FSource[5]^.Y));
585 AssertEquals(3, FSource[5]^.YList[0]);
586
587 FSource.DataPoints.Add('1|2|3||t');
588 AssertEquals(clTAColor, FSource[6]^.Color);
589
590 // Check Text part containing '|' character(s)
591 FSource.DataPoints.Add('1|2|3|?|"a|b|c"');
592 AssertEquals('a|b|c', FSource[7]^.Text);
593
594 // Check Text part containing line ending
595 FSource.DataPoints.Add('1|2|3|?|"a'+LineEnding+'b"');
596 AssertEquals('a'+LineEnding+'b', FSource[8]^.Text);
597
598 // Check Text part containing quotes
599 FSource.DataPoints.Add('1|2|3|?|This is "quoted".');
600 AssertEquals('This is "quoted".', FSource[9]^.Text);
601
602 FSource.DataPoints.Add('1|2|3|?|"This is ""quoted""."');
603 AssertEquals('This is "quoted".', FSource[10]^.Text);
604
605 FSource.DataPoints.Add('1|2|3|?|"This is ""quoted"""');
606 AssertEquals('This is "quoted"', FSource[11]^.Text);
607
608 FSource.DataPoints.Add('1|2|3|?|Single ".');
609 AssertEquals('Single ".', FSource[12]^.Text);
610
611 FSource.DataPoints.Add('1|2|3|?|Two quotes "".');
612 AssertEquals('Two quotes "".', FSource[13]^.Text);
613
614 // Check Text part containing separator and quotes
615 FSource.DataPoints.Add('1|2|3|?|"Number of ""|"" items"');
616 AssertEquals('Number of "|" items', FSource[14]^.Text);
617
618 // Check multiple x and y values
619 FSource.Clear;
620 FSource.XCount := 2;
621 FSource.YCount := 3;
622 FSource.AddXListYList([1, 2], [3, 4, 5]);
623 AssertEquals(2, FSource.XCount);
624 AssertEquals(3, FSource.YCount);
625 AssertEquals(1, FSource[0]^.X);
626 AssertEquals(2, FSource[0]^.XList[0]);
627 AssertEquals(3, FSource[0]^.Y);
628 AssertEquals(4, FSource[0]^.YList[0]);
629 AssertEquals(5, FSource[0]^.YList[1]);
630
631 FSource.DataPoints.Add('10|20|30|40|50|?|t');
632 AssertEquals(10, FSource[1]^.X);
633 AssertEquals(20, FSource[1]^.XList[0]);
634 AssertEquals(30, FSource[1]^.Y);
635 AssertEquals(40, FSource[1]^.YList[0]);
636 AssertEquals(50, FSource[1]^.YList[1]);
637
638 // Add multiple strings in a single AddText command
639 FSource.Clear;
640 FSource.XCount := 2;
641 FSource.YCount := 3;
642 FSource.DataPoints.AddText('100|200|300|400|500|?|Data1' + LineEnding +
643 '101|201|301|401|501|?|Data2');
644 AssertEquals(2, FSource.Count);
645 AssertEquals(2, FSource.XCount);
646 AssertEquals(3, FSource.YCount);
647 AssertEquals(100, FSource[0]^.X);
648 AssertEquals(200, FSource[0]^.XList[0]);
649 AssertEquals(300, FSource[0]^.Y);
650 AssertEquals(500, FSource[0]^.YList[1]);
651 AssertEquals('Data1', FSource[0]^.Text);
652 AssertEquals(101, FSource[1]^.X);
653 AssertEquals(501, FSource[1]^.YList[1]);
654 AssertEquals('Data2', FSource[1]^.Text);
655
656 // Add multiple strings in a single AddStrings command
657 FSource.Datapoints.AddStrings(['110|210|310|410|510|?|ABC', '111|211|311|411|511|?|abc']);
658 AssertEquals(4, FSource.Count);
659 AssertEquals(2, FSource.XCount);
660 AssertEquals(3, FSource.YCount);
661 AssertEquals(110, FSource[2]^.X);
662 AssertEquals(210, FSource[2]^.XList[0]);
663 AssertEquals(310, FSource[2]^.Y);
664 AssertEquals(510, FSource[2]^.YList[1]);
665 AssertEquals('ABC', FSource[2]^.Text);
666 AssertEquals(111, FSource[3]^.X);
667 AssertEquals(511, FSource[3]^.YList[1]);
668 AssertEquals('abc', FSource[3]^.Text);
669
670 (*
671 FSource.SetYList(0, [3, 4]);
672 AssertEquals('Extra items are chopped', [3], FSource[0]^.YList);
673 FSource.DataPoints.Add('1|2|3|4|?|t');
674 AssertEquals(3, FSource.YCount);
675 AssertEquals(2, FSource[1]^.Y);
676 AssertEquals([3, 4], FSource[1]^.YList);
677
678 FSource.AddXYList(2, [7, 8, 9]);
679 AssertEquals(3, FSource.YCount);
680 AssertEquals(7, FSource[2]^.Y);
681 AssertEquals([8, 9], FSource[2]^.YList);
682 FSource.AddXYList(3, [10]);
683 AssertEquals(4, FSource.Count);
684 AssertEquals(3, FSource.YCount);
685 AssertEquals(10, FSource[3]^.Y);
686 AssertEquals([0, 0], FSource[3]^.YList);
687 try
688 FSource.AddXYList(4, []);
689 Fail('Empty YList');
690 except on E: Exception do
691 AssertTrue('Empty YList', E is TListChartSource.EYListEmptyError);
692 end;
693 *)
694 end;
695
TListSourceTest.Comparenull696 function TListSourceTest.Compare(AItem1, AItem2: Pointer): Integer;
697 var
698 item1: PChartDataItem absolute AItem1;
699 item2: PChartDataItem absolute AItem2;
700 begin
701 Result := CompareValue(item1^.X + item1^.XList[0], item2^.X + item2^.XList[0]);
702 end;
703
704 procedure TListSourceTest.Sort;
705 begin
706 FSource.Clear;
707 FSource.XCount := 2;
708 FSource.YCount := 2;
709 FSource.AddXListYList([1, -0.1], [10, 100], 'A'); // x1+x2 = 0.9
710 FSource.AddXListYList([9, 0.9], [90, -900], 'M'); // x1+x2 = 9.9
711 FSource.AddXListYList([5, -0.5], [50, 50], 'D'); // x1+x2 = 4.5
712
713 FSource.SortBy := sbX;
714 FSource.SortIndex := 0;
715 FSource.SortDir := sdAscending;
716 FSource.Sorted := true;
717 AssertEquals(1, FSource[0]^.X);
718 AssertEquals(5, FSource[1]^.X);
719 AssertEquals(9, FSource[2]^.X);
720
721 FSource.SortBy := sbX;
722 FSource.SortIndex := 1;
723 AssertEquals(-0.5, FSource[0]^.XList[0]);
724 AssertEquals(-0.1, FSource[1]^.XList[0]);
725 AssertEquals( 0.9, FSource[2]^.XList[0]);
726
727 FSource.SortBy := sbY;
728 FSource.SortIndex := 0;
729 AssertEquals(10, FSource[0]^.Y);
730 AssertEquals(50, FSource[1]^.Y);
731 AssertEquals(90, FSource[2]^.Y);
732
733 FSource.SortBy := sbY;
734 FSource.SortIndex := 1;
735 FSource.SortDir := sdDescending;
736 AssertEquals(100, FSource[0]^.YList[0]);
737 AssertEquals(50, FSource[1]^.YList[0]);
738 AssertEquals(-900, FSource[2]^.YList[0]);
739
740 FSource.SortBy := sbText;
741 FSource.SortDir := sdDescending;
742 AssertEquals('M', FSource[0]^.Text);
743 AssertEquals('D', FSource[1]^.Text);
744 AssertEquals('A', FSource[2]^.Text);
745
746 FSource.OnCompare := @Compare;
747 FSource.SortBy := sbCustom;
748 FSource.SortDir := sdAscending;
749 AssertEquals(1, FSource[0]^.X);
750 AssertEquals(5, FSource[1]^.X);
751 AssertEquals(9, FSource[2]^.X);
752
753 FSource.OnCompare := nil;
754 FSource.Sorted := false;
755 end;
756
757 procedure TListSourceTest.SetUp;
758 begin
759 inherited SetUp;
760 FSource := TListChartSource.Create(nil);
761 end;
762
763 procedure TListSourceTest.TearDown;
764 begin
765 FreeAndNil(FSource);
766 inherited TearDown;
767 end;
768
769 { TRandomSourceTest }
770
771 procedure TRandomSourceTest.Extent;
772 var
773 s: TRandomChartSource;
774 ext: TDoubleRect;
775 begin
776 s := TRandomChartSource.Create(nil);
777 try
778 s.XMin := 10;
779 s.XMax := 20;
780 s.YMin := 5;
781 s.YMax := 6;
782 s.PointsNumber := 1000;
783 ext := s.Extent;
784 AssertEquals(10, ext.a.X);
785 AssertEquals(20, ext.b.X);
786 Assert(ext.a.Y > 5);
787 Assert(ext.b.Y < 6);
788 Assert(ext.a.Y < ext.b.Y);
789 finally
790 s.Free;
791 end;
792 end;
793
794 { TIntervalSourceTest }
795
796 procedure TIntervalSourceTest.AssertValueEquals(
797 const AExpected: array of Double; const AActual: TChartValueTextArray);
798 var
799 i: Integer;
800 a: array of Double;
801 begin
802 SetLength(a, Length(AActual));
803 for i := 0 to High(AActual) do
804 a[i] := AActual[i].FValue;
805 AssertEquals(AExpected, a, 1e-6);
806 end;
807
808 procedure TIntervalSourceTest.IntervalSource;
809 var
810 p: TValuesInRangeParams;
811 src: TIntervalChartSource;
812 r: TChartValueTextArray = nil;
813 begin
814 p := VDummyTransform.PrepareValuesInRangeParams;
815 src := TIntervalChartSource.Create(nil);
816 try
817 src.Params.MaxLength := 15;
818 src.ValuesInRange(p, r);
819 AssertValueEquals([20, 30, 40, 50, 60, 70], r);
820 src.Params.Options := [aipUseCount];
821 src.Params.Count := 7;
822 src.Params.Tolerance := 1;
823 src.ValuesInRange(p, r);
824 AssertValueEquals([24, 30, 36, 41, 47, 52, 58, 63, 69, 75], r);
825 finally
826 p.FIntervals.Free;
827 src.Free;
828 end;
829 end;
830
831 procedure TIntervalSourceTest.ListSource;
832 var
833 i: Integer;
834 p: TValuesInRangeParams;
835 r: TChartValueTextArray = nil;
836 src: TListChartSource;
837
838 procedure Check(const AExpected: array of Double);
839 begin
840 r := nil;
841 src.ValuesInRange(p, r);
842 AssertValueEquals(AExpected, r);
843 end;
844
845 begin
846 p := VDummyTransform.PrepareValuesInRangeParams;
847 p.FFormat := '%4:g';
848 src := TListChartSource.Create(nil);
849 for i := 1 to 10 do
850 src.Add(10 * i, i);
851 try
852 Check([20, 30, 40, 50, 60, 70]);
853 p.FIntervals.MinLength := 20;
854 Check([20, 30, 50, 70]);
855 p.FMin := 81;
856 p.FMax := 82;
857 Check([80, 90]);
858 p.FMin := 9;
859 p.FMax := 11;
860 Check([10, 20]);
861 src.Add(8, 11);
862 Check([8, 10, 20]);
863 p.FMin := 1;
864 p.FMax := 20;
865 p.FIntervals.Options := p.FIntervals.Options - [aipUseMinLength];
866 Check([8, 10, 20, 30]);
867 p.FIntervals.Options := p.FIntervals.Options + [aipUseMinLength];
868 p.FMax := 50;
869 Check([8, 30, 50, 60]);
870 AssertEquals('Lower bound not first in-range value', '8', r[0].FText);
871 src.Sort;
872 Check([8, 30, 50, 60]);
873 p.FIntervals.Tolerance := 3;
874 Check([10, 30, 50, 60]);
875 finally
876 p.FIntervals.Free;
877 src.Free;
878 end;
879 end;
880
881 initialization
882
883 RegisterTests([
884 TListSourceTest, TRandomSourceTest, TCalculatedSourceTest,
885 TIntervalSourceTest]);
886
887 end.
888
889