Add example test, update example READMEs (#91130)

diff --git a/examples/api/README.md b/examples/api/README.md
index b0e6ca1..2c1a878 100644
--- a/examples/api/README.md
+++ b/examples/api/README.md
@@ -1,67 +1,135 @@
 # API Example Code
 
-This directory contains the API sample code that is referenced from the
-API documentation in each class.
+This directory contains the API sample code that is referenced from the API
+documentation in the framework.
 
-They can be run individually by just specifying the path to the example on the
-command line (or in the run configuration of an IDE).
+The examples can be run individually by just specifying the path to the example
+on the command line (or in the run configuration of an IDE).
 
-For example, to run, in Chrome, the first example from the `Curve2D` class, you
-would run it like so, from this [api](.) directory:
+For example (no pun intended!), to run, the first example from the `Curve2D`
+class in Chrome, you would run it like so from the [api](.) directory:
 
 ```
 % flutter run -d chrome lib/animation/curves/curve2_d.0.dart
 ```
 
-These same examples are available on the API docs site. For instance, the
-example above is available on [this
-page](https://api.flutter.dev/flutter/animation/Curve2D-class.html#animation.Curve2D.1).
-Most of them are available as interactive examples in Dartpad, but some just
-don't make sense on the web, and so are available as standalone examples that
-can be run here.
+All of these same examples are available on the API docs site. For instance, the
+example above is available on [this page](
+https://api.flutter.dev/flutter/animation/Curve2D-class.html#animation.Curve2D.1).
+Most of the samples are available as interactive examples in
+[Dartpad](https://dartpad.dev), but some (the ones marked with `{@tool sample}`
+in the framework source code), just don't make sense on the web, and so are
+available as standalone examples that can be run here. For instance, setting the
+system overlay style doesn't make sense on the web (it only changes the
+notification area background color on Android), so you can run the example for
+that on an Android device like so:
+
+```
+% flutter run -d MyAndroidDevice lib/services/system_chrome/system_chrome.set_system_u_i_overlay_style.1.dart
+```
 
 ## Naming
 
 The naming scheme for the files is similar to the hierarchy under
 [packages/flutter/lib/src](../../packages/flutter/lib/src), except that the
-files are represented as directories, and each sample in each file as a separate
-file in that directory. So, for the example above, the examples are from the
+files are represented as directories (without the `.dart` suffix), and each
+sample in the file is a separate file in that directory. So, for the example
+above, where the examples are from the
 [packages/flutter/lib/src/animation/curves.dart](../../packages/flutter/lib/src/animation/curves.dart)
-file, the `Curve2D` class, and the first sample (hence the index "0") for that
-symbol resides in the
-[lib/animation/curves/curve2_d.0.dart](lib/animation/curves/curve2_d.0.dart)
-file.
+file, the `Curve2D` class, the first sample (hence the index "0") for that
+symbol resides in the file named
+[lib/animation/curves/curve2_d.0.dart](lib/animation/curves/curve2_d.0.dart).
+
+Symbol names are converted from "CamelCase" to "snake_case". Dots are left
+between symbol names, so the first example for symbol
+`InputDecoration.prefixIconConstraints` would be converted to
+`input_decoration.prefix_icon_constraints.0.dart`.
+
+If the same example is linked to from multiple symbols, the source will be in
+the canonical location for one of the symbols, and the link in the API docs
+block for the other symbols will point to the first symbol's example location.
 
 ## Authoring
 
-When authoring these examples, place a block like so in the Dartdoc
-documentation for the symbol you would like to attach it to. Here's what it
-might look like if you wanted to add a new example to the `Curve2D` class. First
-add the stub to the symbol documentation:
+> For more detailed information about authoring examples, see
+> [the snippets package](https://pub.dev/packages/snippets).
+
+When authoring examples, first place a block in the Dartdoc documentation for
+the symbol you would like to attach it to. Here's what it might look like if you
+wanted to add a new example to the `Curve2D` class:
 
 ```dart
-/// {@tool dartpad --template=material_scaffold}
+/// {@tool dartpad}
+/// Write a description of the example here. This description will appear in the
+/// API web documentation to introduce the example.
+///
+/// ** See code in examples/api/lib/animation/curves/curve2_d.0.dart **
+/// {@end-tool}
+```
+
+The "See code in" line needs to be formatted exactly as above, with no wrapping
+or newlines, one space after the "`**`" at the beginning, and one space before
+the "`**`" at the end, and the words "See code in" at the beginning of the line.
+This is what the snippets tool and the IDE use when finding the example source
+code that you are creating.
+
+Use `{@tool dartpad}` for Dartpad examples, and use `{@tool sample}` for
+examples that shouldn't be run/shown in Dartpad.
+
+Once that comment block is inserted in the source code, create a new file at the
+appropriate path under [`examples/api`](.). You should also add tests for your
+sample code under [`examples/api/test`](./test).
+
+The entire example should be in a single file, so that Dartpad can load it.
+
+Only packages that can be loaded by Dartpad may be imported. If you use one that
+hasn't been used in an example before, you may have to add it to the
+[pubspec.yaml](pubspec.yaml) in the api directory.
+
+## Snippets
+
+There is another type of example that can also be authored, using `{@tool
+snippet}`. Snippet examples are just written inline in the source, like so:
+
+```dart
+/// {@tool dartpad}
 /// Write a description of the example here. This description will appear in the
 /// API web documentation to introduce the example.
 ///
 /// ```dart
-/// // These are the sections you want to fill out in the template.
-/// // They will be transferred to the example file when you extract it.
+/// // Sample code goes here, e.g.:
+/// const Widget emptyBox = SizedBox();
 /// ```
 /// {@end-tool}
 ```
 
-Then install the `extract_sample` command with:
+The source for these snippets isn't stored under the [`examples/api`](.)
+directory, or available in Dartpad in the API docs, since they're not intended
+to be runnable, they just show some incomplete snippet of example code. It must
+compile (in the context of the sample analyzer), but doesn't need to do
+anything. See [the snippets documentation](
+https://pub.dev/packages/snippets#snippet-tool) for more information about the
+context that the analyzer uses.
 
-```
-% pub global activate snippets
-```
+## Writing Tests
 
-And run the `extract_sample` command from the Flutter repo dir:
+Examples are required to have tests. There is already a "smoke test" that runs
+all the API examples, just to make sure that they start up without crashing. In
+addition, we also require writing tests of functionality in the examples, and
+generally just do what we normally do for writing tests. The one thing that
+makes it more challenging for the examples is that they can't really be written
+for testability in any obvious way, since that would probably complicate the
+example and make it harder to explain.
 
-```
-$ pub global run extract_sample packages/flutter/lib/src/animation/curves.dart
-```
+As an example, in regular framework code, you might include a parameter for a
+`Platform` object that can be overridden by a test to supply a dummy platform,
+but in the example, this would be unnecessary complexity for the example. In all
+other ways, these are just normal tests.
 
-This will create a new file in the `examples/api` directory, in this case it
-would create `examples/api/lib/animation/curves/curve2_d.1.dart`
+Tests go into a directory under [test](./test) that matches their location under
+[lib](./lib). They are named the same as the example they are testing, with
+`_test.dart` at the end, like other tests. For instance, a `LayoutBuilder`
+example that resides in [`lib/widgets/layout_builder/layout_builder.0.dart`](
+./lib/widgets/layout_builder/layout_builder.0.dart) would have its tests in a
+file named [`test/animation/curves/curve2_d.0_test.dart`](
+./test/widgets/layout_builder/layout_builder.0_test.dart)