Skip to content

Commit af2b7a8

Browse files
update test
1 parent 3c00707 commit af2b7a8

File tree

1 file changed

+134
-109
lines changed

1 file changed

+134
-109
lines changed

test/chart/line_chart/line_chart_curve_test.dart

Lines changed: 134 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,26 @@ import 'package:fl_chart/fl_chart.dart';
44
import 'package:fl_chart/src/chart/line_chart/line_chart_curve.dart';
55
import 'package:flutter_test/flutter_test.dart';
66

7-
void expectLikeStraightLine(
8-
LineChartCurve curve, {
9-
Offset point0 = Offset.zero,
10-
Offset point1 = const Offset(10, 10),
11-
}) {
12-
final path = Path()..moveTo(point0.dx, point0.dy);
13-
curve.appendToPath(path, point0, point1, null);
14-
15-
final metrics = path.computeMetrics().toList();
16-
expect(metrics.length, 1);
17-
expect(metrics.single.length, closeTo(point1.distanceTo(point0), 0.001));
18-
}
7+
const samplePoints1 = [
8+
Offset(10, 10),
9+
Offset(20, 20),
10+
Offset(30, 40),
11+
Offset(40, 10),
12+
];
1913

2014
void main() {
15+
test('static constructor', () {
16+
expect(LineChartCurve.noCurve, equals(const LineChartNoCurve()));
17+
expect(
18+
LineChartCurve.cubicTension(),
19+
equals(const LineChartCubicTensionCurve()),
20+
);
21+
expect(
22+
LineChartCurve.cubicMonotone(),
23+
equals(const LineChartCubicMonotoneCurve()),
24+
);
25+
});
26+
2127
group('LineChartNoCurve', () {
2228
test('equality check', () {
2329
const a = LineChartNoCurve();
@@ -51,26 +57,59 @@ void main() {
5157
expect(a.hashCode, equals(b.hashCode));
5258
});
5359

54-
test('no curve case', () {
55-
const curve = LineChartCubicTensionCurve();
60+
test('lerp no curve', () {
61+
const curve = LineChartCubicTensionCurve(smoothness: 0.8);
5662

5763
expect(
58-
curve.noCurveCase,
59-
equals(
60-
LineChartCubicTensionCurve(
61-
smoothness: 0,
62-
preventCurveOverShooting: curve.preventCurveOverShooting,
63-
preventCurveOvershootingThreshold:
64-
curve.preventCurveOvershootingThreshold,
65-
),
66-
),
64+
lerpCurve(curve, const LineChartNoCurve(), 0.5),
65+
equals(const LineChartCubicTensionCurve(smoothness: 0.4)),
6766
);
6867
});
6968

7069
test('CubicTensionCurve with smoothness = 0 behaves like straight line',
7170
() {
7271
expectLikeStraightLine(const LineChartCubicTensionCurve(smoothness: 0));
7372
});
73+
74+
test(
75+
'prevents overshoot when dy difference is below threshold in y direction',
76+
() {
77+
const curve = LineChartCubicTensionCurve(
78+
preventCurveOverShooting: true,
79+
);
80+
81+
// Create points where dy difference is below threshold (5 < 10)
82+
final points = [
83+
Offset.zero,
84+
const Offset(20, 5), // dy = 5
85+
const Offset(40, 8), // dy = 3
86+
];
87+
88+
final path = _buildPathWithCurve(points, curve);
89+
90+
final metrics = path.computeMetrics().toList();
91+
expect(metrics.length, 1);
92+
});
93+
94+
test(
95+
'prevents overshoot when dx difference is below threshold in x direction',
96+
() {
97+
const curve = LineChartCubicTensionCurve(
98+
preventCurveOverShooting: true,
99+
);
100+
101+
// Create points where dx difference is below threshold (5 < 10)
102+
final points = [
103+
Offset.zero,
104+
const Offset(5, 20), // dx = 5
105+
const Offset(8, 40), // dx = 3
106+
];
107+
108+
final path = _buildPathWithCurve(points, curve);
109+
110+
final metrics = path.computeMetrics().toList();
111+
expect(metrics.length, 1);
112+
});
74113
});
75114

76115
group('LineChartCubicMonotoneCurve', () {
@@ -82,122 +121,98 @@ void main() {
82121
expect(a.hashCode, equals(b.hashCode));
83122
});
84123

85-
test('no curve case', () {
86-
const curve = LineChartCubicMonotoneCurve();
124+
test('lerp no curve', () {
125+
const curve = LineChartCubicMonotoneCurve(smooth: 0.8);
87126

88127
expect(
89-
curve.noCurveCase,
90-
equals(
91-
LineChartCubicMonotoneCurve(
92-
smooth: 0,
93-
monotone: curve.monotone,
94-
tinyThresholdSquared: curve.tinyThresholdSquared,
95-
),
96-
),
128+
lerpCurve(const LineChartNoCurve(), curve, 0.5),
129+
equals(const LineChartCubicMonotoneCurve(smooth: 0.4)),
97130
);
98131
});
99132

100-
group('smooth parameter behavior', () {
101-
test('smooth = 0 produces straight line', () {
102-
expectLikeStraightLine(
103-
const LineChartCubicMonotoneCurve(smooth: 0),
104-
);
105-
});
106-
107-
test('smooth = 0.3 produces curved line shorter than smooth = 0.7', () {
108-
final points = [
109-
Offset.zero,
110-
const Offset(10, 10),
111-
const Offset(20, 5),
112-
const Offset(30, 15),
113-
];
114-
115-
final path1 = _buildPathWithCurve(
116-
points,
117-
const LineChartCubicMonotoneCurve(smooth: 0.3),
118-
);
119-
final path2 = _buildPathWithCurve(
120-
points,
121-
const LineChartCubicMonotoneCurve(smooth: 0.7),
122-
);
123-
124-
final metrics1 = path1.computeMetrics().toList();
125-
final metrics2 = path2.computeMetrics().toList();
133+
test('draw straight line if just two points', () {
134+
expectLikeStraightLine(
135+
const LineChartCubicMonotoneCurve(tinyThresholdSquared: 0),
136+
points: [Offset.zero, const Offset(10, 10)],
137+
);
138+
});
126139

127-
expect(metrics1.length, 1);
128-
expect(metrics2.length, 1);
140+
test('draw straight line if smooth = 0', () {
141+
expectLikeStraightLine(
142+
const LineChartCubicMonotoneCurve(
143+
smooth: 0,
144+
tinyThresholdSquared: double.infinity,
145+
),
146+
);
147+
});
129148

130-
// Higher smooth value should produce longer curved path
131-
expect(
132-
metrics2.single.length,
133-
greaterThan(metrics1.single.length),
149+
group('tinyThreshold parameter behavior', () {
150+
test('draw straight line if distance < tinyThreshold', () {
151+
expectLikeStraightLine(
152+
const LineChartCubicMonotoneCurve(
153+
tinyThresholdSquared: double.infinity,
154+
),
134155
);
135156
});
136157

137-
test('smooth = 1.0 produces maximum smoothness', () {
138-
final points = [
139-
Offset.zero,
140-
const Offset(10, 10),
141-
const Offset(20, 5),
142-
];
143-
158+
test('draw curved line if distance > tinyThreshold', () {
144159
final path = _buildPathWithCurve(
145-
points,
146-
const LineChartCubicMonotoneCurve(smooth: 1),
160+
samplePoints1,
161+
const LineChartCubicMonotoneCurve(tinyThresholdSquared: 0),
147162
);
148163

149164
final metrics = path.computeMetrics().toList();
150-
expect(metrics.length, 1);
151-
// Curved path should be longer than straight line
165+
152166
expect(
153167
metrics.single.length,
154-
greaterThan(
155-
points[0].distanceTo(points[1]) + points[1].distanceTo(points[2]),
156-
),
168+
greaterThan(samplePoints1.straightDistance),
157169
);
158170
});
159171
});
160172

161-
group('state management (_flag)', () {
162-
test('flag resets after last point', () {
163-
final points = [
164-
Offset.zero,
165-
const Offset(10, 10),
166-
const Offset(20, 5),
167-
];
168-
169-
// First path
170-
final path1 = _buildPathWithCurve(
171-
points,
172-
const LineChartCubicMonotoneCurve(),
173-
);
174-
175-
// Second path should not be affected by first path's flag
176-
final path2 = _buildPathWithCurve(
177-
points,
178-
const LineChartCubicMonotoneCurve(),
179-
);
180-
181-
final metrics1 = path1.computeMetrics().toList();
182-
final metrics2 = path2.computeMetrics().toList();
183-
184-
// Both paths should have identical length
185-
expect(
186-
metrics1.single.length,
187-
closeTo(metrics2.single.length, 0.001),
188-
);
173+
group('smooth parameter behavior', () {
174+
test('the effect of smooth increases monotonically', () {
175+
var smoothCount = 1;
176+
var lastCurveLength = samplePoints1.straightDistance;
177+
178+
while (smoothCount < 11) {
179+
final smooth = 0.1 * smoothCount;
180+
181+
final path = _buildPathWithCurve(
182+
samplePoints1,
183+
LineChartCubicMonotoneCurve(
184+
smooth: smooth,
185+
tinyThresholdSquared: 0,
186+
),
187+
);
188+
final curveLength = path.computeMetrics().single.length;
189+
expect(curveLength, greaterThanOrEqualTo(lastCurveLength));
190+
lastCurveLength = curveLength;
191+
smoothCount++;
192+
}
189193
});
190194
});
191195
});
192196
}
193197

198+
void expectLikeStraightLine(
199+
LineChartCurve curve, {
200+
List<Offset> points = samplePoints1,
201+
}) {
202+
final path = _buildPathWithCurve(points, curve);
203+
204+
final metrics = path.computeMetrics().toList();
205+
expect(metrics.single.length, closeTo(points.straightDistance, 0.001));
206+
}
207+
194208
/// Helper function to build a complete path with the given curve
195209
Path _buildPathWithCurve(List<Offset> points, LineChartCurve curve) {
210+
final path = Path();
196211
if (points.isEmpty) {
197-
return Path();
212+
return path;
198213
}
199214

200-
final path = Path()..moveTo(points[0].dx, points[0].dy);
215+
path.moveTo(points[0].dx, points[0].dy);
201216

202217
for (var i = 1; i < points.length; i++) {
203218
final previous = points[i - 1];
@@ -213,3 +228,13 @@ Path _buildPathWithCurve(List<Offset> points, LineChartCurve curve) {
213228
extension on Offset {
214229
double distanceTo(Offset other) => (this - other).distance;
215230
}
231+
232+
extension on List<Offset> {
233+
double get straightDistance {
234+
double distance = 0;
235+
for (var i = 1; i < length; i++) {
236+
distance += this[i].distanceTo(this[i - 1]);
237+
}
238+
return distance;
239+
}
240+
}

0 commit comments

Comments
 (0)