Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions lib/features/erd/erd_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -678,14 +678,32 @@ class _ErdViewState extends material.State<ErdView> {
onAction: _load,
),
);
} else if (full != null && full.tables.isNotEmpty && schema!.isEmpty) {
// Every table was hidden from the diagram: they exist, so say so and
// offer them back instead of "No tables found".
body = material.Center(
child: QueryaEmptyState(
icon: material.Icon(material.Icons.visibility_off_outlined,
color: wb.mutedForeground),
title: 'All tables are hidden',
description: '${_hidden.length} '
'${_hidden.length == 1 ? 'table is' : 'tables are'} hidden '
'from the diagram.',
actionLabel: 'Show all tables',
onAction: _showAllTables,
),
);
} else if (schema == null || layout == null || schema.isEmpty) {
final db = widget.databaseName;
body = material.Center(
child: QueryaEmptyState(
icon: material.Icon(material.Icons.table_chart_outlined,
color: wb.mutedForeground),
title: 'No tables found',
description:
'This schema has no tables, or this role cannot see them.',
description: db.isEmpty
? 'This schema has no tables, or this role cannot see them.'
: 'The current schema of $db has no tables, or this role '
'cannot see them.',
),
);
} else if (widget.neighbourhoodDepth != null &&
Expand Down
77 changes: 77 additions & 0 deletions test/features/erd/erd_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,83 @@ void main() {
closeTo(height, 0.5));
});

testWidgets('Copy Mermaid puts the diagram on the clipboard', (t) async {
await t.binding.setSurfaceSize(const material.Size(1200, 800));
String? copied;
t.binding.defaultBinaryMessenger.setMockMethodCallHandler(
SystemChannels.platform, (call) async {
if (call.method == 'Clipboard.setData') {
copied = (call.arguments as Map)['text'] as String?;
}
return null;
});
addTearDown(() => t.binding.defaultBinaryMessenger
.setMockMethodCallHandler(SystemChannels.platform, null));
await t.pumpWidget(queryaThemeTestShell(
child: ErdView(
source: SqlErdSource(delegate: delegate(), dialect: SqlDialect.sqlite)),
));
await t.pump();
await t.pump();

await t.tap(find.byKey(const material.ValueKey('erd_export')));
await t.pump();
await t.tap(find.text('Copy Mermaid'));
await t.pump();
expect(copied, startsWith('erDiagram'));
expect(copied, contains('users ||--|{ orders'));
// The toast's 5 s timer starts after its entry animation: step the
// clock frame by frame until it has gone.
for (var i = 0; i < 10; i++) {
await t.pump(const Duration(seconds: 1));
}
});

testWidgets('hiding every table says so and offers them back',
variant: desktop, (t) async {
await t.binding.setSurfaceSize(const material.Size(1200, 800));
await t.pumpWidget(queryaThemeTestShell(
child: ErdView(
source: SqlErdSource(delegate: delegate(), dialect: SqlDialect.sqlite)),
));
await t.pump();
await t.pump();

for (final table in ['users', 'orders']) {
await t.tap(find.byKey(material.ValueKey('erd_table_$table')),
buttons: kSecondaryButton);
await t.pump();
await t.pump(const Duration(milliseconds: 300));
await t.tap(find.text('Hide from diagram'));
// Let the menu popover close, or it takes the next tap.
await t.pumpAndSettle();
}
expect(find.text('All tables are hidden'), findsOneWidget);
expect(find.text('No tables found'), findsNothing);

await t.tap(find.text('Show all tables'));
await t.pump();
await t.pump();
expect(find.byKey(const material.ValueKey('erd_table_users')),
findsOneWidget);
});

testWidgets('an empty schema names the database', (t) async {
await t.pumpWidget(queryaThemeTestShell(
child: ErdView(
source: SqlErdSource(
delegate: FakeSqlExecutionDelegate(
onExecute: (_) => const SqlExecutionResult()),
dialect: SqlDialect.postgres),
databaseName: 'shop',
),
));
await t.pump();
await t.pump();
expect(find.text('No tables found'), findsOneWidget);
expect(find.textContaining('shop'), findsOneWidget);
});

testWidgets('a card can be dragged and Auto layout puts it back',
(t) async {
await t.binding.setSurfaceSize(const material.Size(1200, 800));
Expand Down
Loading