Skip to content

Commit d6c0d6f

Browse files
authored
[ Widget Previews ] Add widget_preview_scaffold.shard to test the widget_preview_scaffold template contents (flutter#166358)
Adds a new `widget_preview_scaffold.shard` directory which contains a hydrated `widget_preview_scaffold` template. This will allow for us to write widget tests against the widgets defined in the templates. This PR doesn't add any widget tests and is only adding the ability to run these tests in follow up changes. Fixes flutter#166416
1 parent a400e79 commit d6c0d6f

23 files changed

+984
-14
lines changed

.ci.yaml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,6 +1589,29 @@ targets:
15891589
- engine/**
15901590
- DEPS
15911591

1592+
- name: Linux tool_tests_widget_preview_scaffold
1593+
recipe: flutter/flutter_drone
1594+
timeout: 60
1595+
bringup: true
1596+
properties:
1597+
add_recipes_cq: "true"
1598+
dependencies: >-
1599+
[
1600+
{"dependency": "android_sdk", "version": "version:35v1"},
1601+
{"dependency": "open_jdk", "version": "version:21"}
1602+
]
1603+
shard: tool_tests
1604+
subshard: widget_preview_scaffold
1605+
tags: >
1606+
["framework", "hostonly", "shard", "linux"]
1607+
runIf:
1608+
- dev/**
1609+
- packages/flutter_tools/**
1610+
- bin/**
1611+
- .ci.yaml
1612+
- engine/**
1613+
- DEPS
1614+
15921615
- name: Linux_android_emu android_engine_vulkan_tests
15931616
recipe: flutter/flutter_drone
15941617
timeout: 60

dev/bots/test.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,17 @@ Future<void> _runIntegrationToolTests() async {
236236
);
237237
}
238238

239+
Future<void> _runWidgetPreviewScaffoldToolTests() async {
240+
await runFlutterTest(
241+
path.join(_toolsPath, 'test', 'widget_preview_scaffold.shard', 'widget_preview_scaffold'),
242+
);
243+
}
244+
239245
Future<void> _runToolTests() async {
240246
await selectSubshard(<String, ShardRunner>{
241247
'general': _runGeneralToolTests,
242248
'commands': _runCommandsToolTests,
249+
'widget_preview_scaffold': _runWidgetPreviewScaffoldToolTests,
243250
});
244251
}
245252

packages/flutter_tools/lib/src/commands/widget_preview.dart

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -137,13 +137,20 @@ final class WidgetPreviewStartCommand extends WidgetPreviewSubCommandBase with C
137137
kHeadlessWeb,
138138
help: 'Launches Chrome in headless mode for testing.',
139139
hide: !verboseHelp,
140+
)
141+
..addOption(
142+
kWidgetPreviewScaffoldOutputDir,
143+
help:
144+
'Generated the widget preview environment scaffolding at a given location '
145+
'for testing purposes.',
140146
);
141147
}
142148

143149
static const String kWidgetPreviewScaffoldName = 'widget_preview_scaffold';
144150
static const String kLaunchPreviewer = 'launch-previewer';
145151
static const String kUseFlutterDesktop = 'desktop';
146152
static const String kHeadlessWeb = 'headless-web';
153+
static const String kWidgetPreviewScaffoldOutputDir = 'scaffold-output-dir';
147154

148155
@override
149156
Future<Set<DevelopmentArtifact>> get requiredArtifacts async => const <DevelopmentArtifact>{
@@ -189,30 +196,36 @@ final class WidgetPreviewStartCommand extends WidgetPreviewSubCommandBase with C
189196
);
190197

191198
late final PreviewCodeGenerator _previewCodeGenerator;
192-
late final PreviewManifest _previewManifest;
199+
late final PreviewManifest _previewManifest = PreviewManifest(
200+
logger: logger,
201+
rootProject: rootProject,
202+
fs: fs,
203+
cache: cache,
204+
);
193205

194206
/// The currently running instance of the widget preview scaffold.
195207
AppInstance? _widgetPreviewApp;
196208

197209
@override
198210
Future<FlutterCommandResult> runCommand() async {
199-
final Directory widgetPreviewScaffold = rootProject.widgetPreviewScaffold;
200-
_previewManifest = PreviewManifest(
201-
logger: logger,
202-
rootProject: rootProject,
203-
fs: fs,
204-
cache: cache,
205-
);
211+
final String? customPreviewScaffoldOutput = stringArg(kWidgetPreviewScaffoldOutputDir);
212+
final Directory widgetPreviewScaffold =
213+
customPreviewScaffoldOutput != null
214+
? fs.directory(customPreviewScaffoldOutput)
215+
: rootProject.widgetPreviewScaffold;
206216

207217
// Check to see if a preview scaffold has already been generated. If not,
208218
// generate one.
209-
final bool generateScaffoldProject = _previewManifest.shouldGenerateProject();
219+
final bool generateScaffoldProject =
220+
customPreviewScaffoldOutput != null || _previewManifest.shouldGenerateProject();
210221
// TODO(bkonyi): can this be moved?
211222
widgetPreviewScaffold.createSync();
212223

213224
if (generateScaffoldProject) {
214225
// WARNING: this log message is used by test/integration.shard/widget_preview_test.dart
215-
logger.printStatus('Creating widget preview scaffolding at: ${widgetPreviewScaffold.path}');
226+
logger.printStatus(
227+
'Creating widget preview scaffolding at: ${widgetPreviewScaffold.absolute.path}',
228+
);
216229
await generateApp(
217230
<String>['app', kWidgetPreviewScaffoldName],
218231
widgetPreviewScaffold,
@@ -230,6 +243,9 @@ final class WidgetPreviewStartCommand extends WidgetPreviewSubCommandBase with C
230243
overwrite: true,
231244
generateMetadata: false,
232245
);
246+
if (customPreviewScaffoldOutput != null) {
247+
return FlutterCommandResult.success();
248+
}
233249
_previewManifest.generate();
234250

235251
// WARNING: this access of widgetPreviewScaffoldProject needs to happen
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# {{titleCaseProjectName}}
1+
# Widget Preview Scaffold
22

33
This project is generated by `flutter widget-preview` and is used to host Widgets
44
to be previewed in the widget previewer.

packages/flutter_tools/templates/widget_preview_scaffold/lib/src/generated_preview.dart.tmpl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
import 'package:flutter/widgets.dart';
65
import 'widget_preview.dart';
76

87
List<WidgetPreview> previews() => <WidgetPreview>[];

packages/flutter_tools/templates/widget_preview_scaffold/lib/src/widget_preview.dart.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,4 @@ class WidgetPreview {
5050
/// If not provided, the default text scaling factor provided by [MediaQuery]
5151
/// will be used.
5252
final double? textScaleFactor;
53-
}
53+
}

packages/flutter_tools/templates/widget_preview_scaffold/pubspec.yaml.tmpl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: {{projectName}}
1+
name: widget_preview_scaffold
22
description: Scaffolding for Flutter Widget Previews
33
publish_to: 'none'
44
version: 0.0.1
@@ -11,6 +11,9 @@ dependencies:
1111
sdk: flutter
1212
flutter_test:
1313
sdk: flutter
14+
# These will be replaced with proper constraints after the template is hydrated.
15+
flutter_lints: any
16+
stack_trace: any
1417

1518
flutter:
1619
uses-material-design: true
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# The generated web assets aren't needed for widget_preview_scaffold widget tests
2+
/widget_preview_scaffold/web/
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Widget Preview Scaffold Testing
2+
3+
This directory contains a hydrated instance of the `widget_preview_scaffold` project template that's used for generating the environment used by `flutter widget-preview start` to host Widget Previews, as well as utilities to detect if the hydrated instance is outdated when compared to the template files.
4+
5+
# Updating the Hydrated Template
6+
7+
If any of the `widget_preview_scaffold` template files are updated, `widget_preview_scaffold/test/template_change_detection_smoke_test.dart` will fail to indicate that the hydrated scaffold needs to be regenerated. To do this, run `dart test/widget_preview_scaffold.shard/update_widget_preview_scaffold.dart` to regenerate the project.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:io';
6+
7+
import 'package:path/path.dart' as path; // flutter_ignore: package_path_import
8+
9+
import 'widget_preview_scaffold/test/widget_preview_scaffold_test_utils.dart';
10+
11+
/// Regenerates the widget_preview_scaffold if needed.
12+
void main() {
13+
if (WidgetPreviewScaffoldTestUtils.checkForTemplateUpdates(
14+
widgetPreviewScaffoldProject: Directory(
15+
Platform.script.resolve('widget_preview_scaffold/').path,
16+
),
17+
widgetPreviewScaffoldTemplateDir: Directory(
18+
Platform.script.resolve(path.join('..', '..', 'templates', 'widget_preview_scaffold')).path,
19+
),
20+
)) {
21+
stdout.writeln('Changes detected in the widget_preview_scaffold project templates.');
22+
stdout.writeln('Regenerating...');
23+
final List<String> args = <String>[
24+
'widget-preview',
25+
'start',
26+
'--scaffold-output-dir=${Platform.script.resolve('widget_preview_scaffold').path}',
27+
];
28+
stdout.writeln('Executing: flutter ${args.join(' ')}');
29+
final ProcessResult result = Process.runSync('flutter', args);
30+
stdout.writeln(result.stdout);
31+
stderr.writeln(result.stderr);
32+
stdout.writeln('Regenerated widget_preview_scaffold.');
33+
} else {
34+
stdout.writeln('No changes detected in the widget_preview_scaffold project templates.');
35+
}
36+
}

0 commit comments

Comments
 (0)