blob: 6e670b78351224aaa219105d90c3971fd1fd99d2 [file] [log] [blame] [view]
Greg Spencer33403bd2021-08-25 09:45:12 -07001# API Example Code
2
Greg Spencer983cbb22021-10-04 13:53:02 -07003This directory contains the API sample code that is referenced from the API
4documentation in the framework.
Greg Spencer33403bd2021-08-25 09:45:12 -07005
Greg Spencer983cbb22021-10-04 13:53:02 -07006The examples can be run individually by just specifying the path to the example
7on the command line (or in the run configuration of an IDE).
Greg Spencer33403bd2021-08-25 09:45:12 -07008
Albertob44cbe12022-02-28 21:41:20 +01009For example (no pun intended!), to run the first example from the `Curve2D`
Greg Spencer983cbb22021-10-04 13:53:02 -070010class in Chrome, you would run it like so from the [api](.) directory:
Greg Spencer33403bd2021-08-25 09:45:12 -070011
12```
13% flutter run -d chrome lib/animation/curves/curve2_d.0.dart
14```
15
Greg Spencer983cbb22021-10-04 13:53:02 -070016All of these same examples are available on the API docs site. For instance, the
17example above is available on [this page](
18https://api.flutter.dev/flutter/animation/Curve2D-class.html#animation.Curve2D.1).
19Most of the samples are available as interactive examples in
20[Dartpad](https://dartpad.dev), but some (the ones marked with `{@tool sample}`
21in the framework source code), just don't make sense on the web, and so are
22available as standalone examples that can be run here. For instance, setting the
23system overlay style doesn't make sense on the web (it only changes the
24notification area background color on Android), so you can run the example for
25that on an Android device like so:
26
27```
28% flutter run -d MyAndroidDevice lib/services/system_chrome/system_chrome.set_system_u_i_overlay_style.1.dart
29```
Greg Spencer33403bd2021-08-25 09:45:12 -070030
31## Naming
32
33The naming scheme for the files is similar to the hierarchy under
34[packages/flutter/lib/src](../../packages/flutter/lib/src), except that the
Greg Spencer983cbb22021-10-04 13:53:02 -070035files are represented as directories (without the `.dart` suffix), and each
36sample in the file is a separate file in that directory. So, for the example
37above, where the examples are from the
Greg Spencer33403bd2021-08-25 09:45:12 -070038[packages/flutter/lib/src/animation/curves.dart](../../packages/flutter/lib/src/animation/curves.dart)
Greg Spencer983cbb22021-10-04 13:53:02 -070039file, the `Curve2D` class, the first sample (hence the index "0") for that
40symbol resides in the file named
41[lib/animation/curves/curve2_d.0.dart](lib/animation/curves/curve2_d.0.dart).
42
43Symbol names are converted from "CamelCase" to "snake_case". Dots are left
44between symbol names, so the first example for symbol
45`InputDecoration.prefixIconConstraints` would be converted to
46`input_decoration.prefix_icon_constraints.0.dart`.
47
48If the same example is linked to from multiple symbols, the source will be in
49the canonical location for one of the symbols, and the link in the API docs
50block for the other symbols will point to the first symbol's example location.
Greg Spencer33403bd2021-08-25 09:45:12 -070051
52## Authoring
53
Greg Spencer983cbb22021-10-04 13:53:02 -070054> For more detailed information about authoring examples, see
55> [the snippets package](https://pub.dev/packages/snippets).
56
57When authoring examples, first place a block in the Dartdoc documentation for
58the symbol you would like to attach it to. Here's what it might look like if you
59wanted to add a new example to the `Curve2D` class:
Greg Spencer33403bd2021-08-25 09:45:12 -070060
61```dart
Greg Spencer983cbb22021-10-04 13:53:02 -070062/// {@tool dartpad}
63/// Write a description of the example here. This description will appear in the
64/// API web documentation to introduce the example.
65///
66/// ** See code in examples/api/lib/animation/curves/curve2_d.0.dart **
67/// {@end-tool}
68```
69
70The "See code in" line needs to be formatted exactly as above, with no wrapping
71or newlines, one space after the "`**`" at the beginning, and one space before
72the "`**`" at the end, and the words "See code in" at the beginning of the line.
73This is what the snippets tool and the IDE use when finding the example source
74code that you are creating.
75
76Use `{@tool dartpad}` for Dartpad examples, and use `{@tool sample}` for
77examples that shouldn't be run/shown in Dartpad.
78
79Once that comment block is inserted in the source code, create a new file at the
Youssef Attiae9230ba2022-06-06 13:24:00 -070080appropriate path under [`examples/api`](.) that matches the location of the
81source file they are linked from, and are named for the symbol they are attached
82to, in lower_snake_case, with an index relating to their order within the doc
83comment. So, for the `Curve2D` case, since it's in the `animation` package, in
84a file called `curves.dart`, and it's the first example, it goes in
85`examples/api/lib/animation/curves/curve2_d.0.dart`.
86
87You should also add tests for your sample code under [`examples/api/test`](./test).
Greg Spencer983cbb22021-10-04 13:53:02 -070088
89The entire example should be in a single file, so that Dartpad can load it.
90
91Only packages that can be loaded by Dartpad may be imported. If you use one that
92hasn't been used in an example before, you may have to add it to the
93[pubspec.yaml](pubspec.yaml) in the api directory.
94
95## Snippets
96
97There is another type of example that can also be authored, using `{@tool
98snippet}`. Snippet examples are just written inline in the source, like so:
99
100```dart
101/// {@tool dartpad}
Greg Spencer33403bd2021-08-25 09:45:12 -0700102/// Write a description of the example here. This description will appear in the
103/// API web documentation to introduce the example.
104///
105/// ```dart
Greg Spencer983cbb22021-10-04 13:53:02 -0700106/// // Sample code goes here, e.g.:
107/// const Widget emptyBox = SizedBox();
Greg Spencer33403bd2021-08-25 09:45:12 -0700108/// ```
109/// {@end-tool}
110```
111
Greg Spencer983cbb22021-10-04 13:53:02 -0700112The source for these snippets isn't stored under the [`examples/api`](.)
113directory, or available in Dartpad in the API docs, since they're not intended
114to be runnable, they just show some incomplete snippet of example code. It must
115compile (in the context of the sample analyzer), but doesn't need to do
116anything. See [the snippets documentation](
117https://pub.dev/packages/snippets#snippet-tool) for more information about the
118context that the analyzer uses.
Greg Spencer33403bd2021-08-25 09:45:12 -0700119
Greg Spencer983cbb22021-10-04 13:53:02 -0700120## Writing Tests
Greg Spencer33403bd2021-08-25 09:45:12 -0700121
Greg Spencer983cbb22021-10-04 13:53:02 -0700122Examples are required to have tests. There is already a "smoke test" that runs
123all the API examples, just to make sure that they start up without crashing. In
124addition, we also require writing tests of functionality in the examples, and
125generally just do what we normally do for writing tests. The one thing that
126makes it more challenging for the examples is that they can't really be written
127for testability in any obvious way, since that would probably complicate the
128example and make it harder to explain.
Greg Spencer33403bd2021-08-25 09:45:12 -0700129
Greg Spencer983cbb22021-10-04 13:53:02 -0700130As an example, in regular framework code, you might include a parameter for a
131`Platform` object that can be overridden by a test to supply a dummy platform,
132but in the example, this would be unnecessary complexity for the example. In all
133other ways, these are just normal tests.
Greg Spencer33403bd2021-08-25 09:45:12 -0700134
Greg Spencer983cbb22021-10-04 13:53:02 -0700135Tests go into a directory under [test](./test) that matches their location under
136[lib](./lib). They are named the same as the example they are testing, with
137`_test.dart` at the end, like other tests. For instance, a `LayoutBuilder`
138example that resides in [`lib/widgets/layout_builder/layout_builder.0.dart`](
139./lib/widgets/layout_builder/layout_builder.0.dart) would have its tests in a
Youssef Attiae9230ba2022-06-06 13:24:00 -0700140file named [`test/widgets/layout_builder/layout_builder.0_test.dart`](
Greg Spencer983cbb22021-10-04 13:53:02 -0700141./test/widgets/layout_builder/layout_builder.0_test.dart)