blob: d71c76206edd6daca6560f9fa00bdb5a6d675089 [file]
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'test_case.dart';
/// Renders a list of [TestCase]s as a Markdown table.
class MarkdownRenderer {
final List<TestCase> testCases;
final List<Type> dimensionTypes;
final String prefix;
MarkdownRenderer({
required this.testCases,
required this.dimensionTypes,
this.prefix = '',
});
/// Renders the Markdown table as a string.
String render() {
if (testCases.isEmpty) return '';
// 1. Gather all strings for the table.
final headerStrings = [
'#',
...dimensionTypes.map((t) {
// Default: split CamelCase into spaces (e.g., AndroidApiLevel ->
// Android Api Level).
return t
.toString()
.split('.')
.last
.replaceAllMapped(
RegExp(r'([a-z])([A-Z])'),
(match) => '${match.group(1)} ${match.group(2)}',
);
}),
];
final rowStrings =
testCases
.map(
(config) =>
dimensionTypes
.map((t) => config.values[t]!.toString())
.toList(),
)
.toList();
// 2. Sort rows alphabetically based on the first column.
rowStrings.sort((a, b) {
for (var i = 0; i < a.length; i++) {
final cmp = a[i].compareTo(b[i]);
if (cmp != 0) return cmp;
}
return 0;
});
// 3. Add numbering.
for (var i = 0; i < rowStrings.length; i++) {
rowStrings[i].insert(0, (i + 1).toString());
}
// 4. Calculate max width for each column.
final numColumns = dimensionTypes.length + 1;
final columnWidths = List<int>.filled(numColumns, 0);
for (var i = 0; i < numColumns; i++) {
columnWidths[i] = headerStrings[i].length;
for (final row in rowStrings) {
if (row[i].length > columnWidths[i]) {
columnWidths[i] = row[i].length;
}
}
// Ensure a minimum width for the separator (---)
if (columnWidths[i] < 3) columnWidths[i] = 3;
}
// 5. Format rows with padding.
String formatRow(List<String> cells) {
final paddedCells = <String>[];
for (var i = 0; i < cells.length; i++) {
paddedCells.add(cells[i].padRight(columnWidths[i]));
}
return '$prefix| ${paddedCells.join(' | ')} |';
}
final header = formatRow(headerStrings);
final separator = formatRow(
List<String>.filled(
numColumns,
'---',
).map((s) => s.substring(0, 3)).toList(),
).replaceAll(' ', '-'); // Make separator look like | --- | --- |
// But don't replace the prefix spaces if any.
final actualSeparator = prefix + separator.substring(prefix.length);
final rows = rowStrings.map(formatRow);
return [
'${prefix}This comment is generated. To regenerate, run:',
'$prefix`REGENERATE_TEST_CONFIGS=true dart test`',
prefix.trimRight(),
header,
actualSeparator,
...rows,
].join('\n');
}
}