# API Example Code

This directory contains the API sample code that is referenced from the API
documentation in the framework.

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 (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
```

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 (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, 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

> 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}
/// 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
/// // Sample code goes here, e.g.:
/// const Widget emptyBox = SizedBox();
/// ```
/// {@end-tool}
```

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.

## Writing Tests

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.

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.

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)
