Skip to content

Commit

Permalink
[flutter_svg] Adopt code excerpts (#8181)
Browse files Browse the repository at this point in the history
Converts the README from unmanaged code examples to code excerpted from
analyzed and compiled code.

Part of flutter/flutter#102679
  • Loading branch information
stuartmorgan authored Nov 26, 2024
1 parent 2033119 commit e6932b7
Show file tree
Hide file tree
Showing 11 changed files with 201 additions and 38 deletions.
2 changes: 0 additions & 2 deletions script/configs/temp_exclude_excerpt.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
# TODO(stuartmorgan): Remove everything from this list. See
# https://github.com/flutter/flutter/issues/102679
- espresso
- flutter_svg
- flutter_svg_test
- in_app_purchase/in_app_purchase
- pointer_interceptor
- quick_actions/quick_actions
4 changes: 4 additions & 0 deletions third_party/packages/flutter_svg/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.0.16

* Adopts code excerpts for README.

## 2.0.15

* Fixes `SvgNetworkLoader` not closing internally created http clients.
Expand Down
45 changes: 26 additions & 19 deletions third_party/packages/flutter_svg/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,24 @@ Draw SVG files using Flutter.

Basic usage (to create an SVG rendering widget from an asset):

<?code-excerpt "example/lib/readme_excerpts.dart (SimpleAsset)"?>
```dart
final String assetName = 'assets/image.svg';
const String assetName = 'assets/dart.svg';
final Widget svg = SvgPicture.asset(
assetName,
semanticsLabel: 'Acme Logo'
semanticsLabel: 'Dart Logo',
);
```

You can color/tint the image like so:

<?code-excerpt "example/lib/readme_excerpts.dart (ColorizedAsset)"?>
```dart
final String assetName = 'assets/up_arrow.svg';
const String assetName = 'assets/simple/dash_path.svg';
final Widget svgIcon = SvgPicture.asset(
assetName,
colorFilter: ColorFilter.mode(Colors.red, BlendMode.srcIn),
semanticsLabel: 'A red up arrow'
colorFilter: const ColorFilter.mode(Colors.red, BlendMode.srcIn),
semanticsLabel: 'Red dash paths',
);
```

Expand All @@ -40,13 +42,17 @@ mode.
You can also specify a placeholder widget. The placeholder will display during
parsing/loading (normally only relevant for network access).

<?code-excerpt "example/lib/readme_excerpts.dart (MissingAsset)"?>
```dart
// Will print error messages to the console.
final String assetName = 'assets/image_that_does_not_exist.svg';
const String assetName = 'assets/image_that_does_not_exist.svg';
final Widget svg = SvgPicture.asset(
assetName,
);
```

<?code-excerpt "example/lib/readme_excerpts.dart (AssetWithPlaceholder)"?>
```dart
final Widget networkSvg = SvgPicture.network(
'https://site-that-takes-a-while.com/image.svg',
semanticsLabel: 'A shark?!',
Expand All @@ -58,18 +64,21 @@ final Widget networkSvg = SvgPicture.network(

If you'd like to render the SVG to some other canvas, you can do something like:

<?code-excerpt "example/lib/readme_excerpts.dart (OutputConversion)"?>
```dart
import 'package:flutter_svg/flutter_svg.dart';
final String rawSvg = '''<svg ...>...</svg>''';
final PictureInfo pictureInfo = await vg.loadPicture(SvgStringLoader(rawSvg), null);
import 'dart:ui' as ui;
// ···
const String rawSvg = '''<svg ...>...</svg>''';
final PictureInfo pictureInfo =
await vg.loadPicture(const SvgStringLoader(rawSvg), null);
// You can draw the picture to a canvas:
canvas.drawPicture(pictureInfo.picture);
// You can draw the picture to a canvas:
canvas.drawPicture(pictureInfo.picture);
// Or convert the picture to an image:
final ui.Image image = pictureInfo.picture.toImage(...);
// Or convert the picture to an image:
final ui.Image image = await pictureInfo.picture.toImage(width, height);
pictureInfo.picture.dispose();
pictureInfo.picture.dispose();
```

The `SvgPicture` helps to automate this logic, and it provides some convenience
Expand All @@ -92,13 +101,11 @@ dart run vector_graphics_compiler -i assets/foo.svg -o assets/foo.svg.vec
The output `foo.svg.vec` can be loaded using the default constructor of
`SvgPicture`.

<?code-excerpt "example/lib/readme_excerpts.dart (PrecompiledAsset)"?>
```dart
import 'package:flutter_svg/flutter_svg.dart';
import 'package:vector_graphics/vector_graphics.dart';
final Widget svg = SvgPicture(
const AssetBytesLoader('assets/foo.svg.vec')
);
// ···
const Widget svg = SvgPicture(AssetBytesLoader('assets/foo.svg.vec'));
```

### Check SVG compatibility
Expand Down
103 changes: 103 additions & 0 deletions third_party/packages/flutter_svg/example/lib/readme_excerpts.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file exists solely to host compiled excerpts for README.md, and is not
// intended for use as an actual example application.

// #docregion OutputConversion
import 'dart:ui' as ui;
// #enddocregion OutputConversion

import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
// #docregion PrecompiledAsset
import 'package:vector_graphics/vector_graphics.dart';
// #enddocregion PrecompiledAsset

/// Loads an SVG asset.
Widget loadAsset() {
// #docregion SimpleAsset
const String assetName = 'assets/dart.svg';
final Widget svg = SvgPicture.asset(
assetName,
semanticsLabel: 'Dart Logo',
);
// #enddocregion SimpleAsset
return svg;
}

/// Loads an SVG asset.
Widget loadColorizedAsset() {
// #docregion ColorizedAsset
const String assetName = 'assets/simple/dash_path.svg';
final Widget svgIcon = SvgPicture.asset(
assetName,
colorFilter: const ColorFilter.mode(Colors.red, BlendMode.srcIn),
semanticsLabel: 'Red dash paths',
);
// #enddocregion ColorizedAsset
return svgIcon;
}

/// Demonstrates loading an asset that doesn't exist.
Widget loadMissingAsset() {
// #docregion MissingAsset
// Will print error messages to the console.
const String assetName = 'assets/image_that_does_not_exist.svg';
final Widget svg = SvgPicture.asset(
assetName,
);
// #enddocregion MissingAsset
return svg;
}

/// Demonstrates loading an asset with a placeholder.
// This method should *not* be called in tests, as tests should not be
// attempting to load from random uncontrolled locations. Using a real URL,
// such as a GitHub URL pointing to this package's assets, would make the
// README example harder to understand.
Widget loadNetworkAssetWithPlaceholder() {
// #docregion AssetWithPlaceholder
final Widget networkSvg = SvgPicture.network(
'https://site-that-takes-a-while.com/image.svg',
semanticsLabel: 'A shark?!',
placeholderBuilder: (BuildContext context) => Container(
padding: const EdgeInsets.all(30.0),
child: const CircularProgressIndicator()),
);
// #enddocregion AssetWithPlaceholder
return networkSvg;
}

/// Demonstrates loading a precompiled asset.
// This asset doesn't exist in the example app, but this code can still be run
// to sanity-check the structure of the example code.
Widget loadPrecompiledAsset() {
// #docregion PrecompiledAsset
const Widget svg = SvgPicture(AssetBytesLoader('assets/foo.svg.vec'));
// #enddocregion PrecompiledAsset
return svg;
}

/// Demonstrates converting SVG to another type.
Future<ui.Image> convertSvgOutput() async {
final Canvas canvas = Canvas(ui.PictureRecorder());
const int width = 100;
const int height = 100;

// #docregion OutputConversion
const String rawSvg = '''<svg ...>...</svg>''';
final PictureInfo pictureInfo =
await vg.loadPicture(const SvgStringLoader(rawSvg), null);

// You can draw the picture to a canvas:
canvas.drawPicture(pictureInfo.picture);

// Or convert the picture to an image:
final ui.Image image = await pictureInfo.picture.toImage(width, height);

pictureInfo.picture.dispose();
// #enddocregion OutputConversion
return image;
}
5 changes: 5 additions & 0 deletions third_party/packages/flutter_svg/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ dependencies:
sdk: flutter
flutter_svg:
path: ../
vector_graphics: ^1.1.13

dev_dependencies:
flutter_test:
sdk: flutter

# The following section is specific to Flutter.
flutter:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:flutter_svg_example/readme_excerpts.dart' as excerpts;
import 'package:flutter_test/flutter_test.dart';

void main() {
test('example simple loadAsset works', () async {
final Widget svg = excerpts.loadAsset();
expect(svg, isNotNull);
});

test('example loadAsset with color filter works', () async {
final Widget svg = excerpts.loadAsset();
expect(svg, isNotNull);
});

test('example loadAsset with a non-existent asset works', () async {
final Widget svg = excerpts.loadMissingAsset();
expect(svg, isNotNull);
});

test('example loadAsset with a precompiled asset works', () async {
final Widget svg = excerpts.loadPrecompiledAsset();
expect(svg, isNotNull);
});
}
2 changes: 1 addition & 1 deletion third_party/packages/flutter_svg/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: flutter_svg
description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files.
repository: https://github.com/flutter/packages/tree/main/third_party/packages/flutter_svg
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_svg%22
version: 2.0.15
version: 2.0.16

environment:
sdk: ^3.4.0
Expand Down
4 changes: 4 additions & 0 deletions third_party/packages/flutter_svg_test/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.0.3

* Adopts code excerpts for README.

## 1.0.2

* Transfers the package source from https://github.com/dnfield/flutter_svg
Expand Down
37 changes: 23 additions & 14 deletions third_party/packages/flutter_svg_test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,33 +15,42 @@ configuration of the `BytesLoader` with the giving test attribute.

The following example shows how you can find svgs with the matching `SvgAssetLoader`.

```dart
testWidgets('Finds svg', (WidgetTester widgetTester) async {
final SvgPicture asset = SvgPicture.asset('/test/path/my.svg');
await widgetTester.pumpWidget(asset);
<?code-excerpt "test/flutter_svg_test_test.dart (ByLoader)"?>
```dart
testWidgets('asset svg', (WidgetTester widgetTester) async {
final SvgPicture asset = SvgPicture.asset('test/flutter_logo.svg');
await widgetTester.pumpWidget(
DefaultAssetBundle(
bundle: _FakeAssetBundle(),
child: asset,
),
);
expect(find.svg(asset.bytesLoader), findsOneWidget);
});
```

#### Find by svg path

Sometimes it is more convenient instead of instantiate the whole `BytesLoader` to
compare only specific attributes.
Sometimes it is more convenient instead of instantiating the whole `BytesLoader`
to compare only specific attributes.

The following example shows how you can find svgs with the specified attribute.

```dart
<?code-excerpt "test/flutter_svg_test_test.dart (ByPath)"?>
```dart
testWidgets('asset svg with path', (WidgetTester widgetTester) async {
const String svgPath = 'test/flutter_logo.svg';
await widgetTester.pumpWidget(SvgPicture.asset(svgPath));
await widgetTester.pumpWidget(
DefaultAssetBundle(
bundle: _FakeAssetBundle(),
child: SvgPicture.asset(svgPath),
),
);
expect(find.svgAssetWithPath(svgPath), findsOneWidget);
});
```
```

## Commemoration

Expand Down
2 changes: 1 addition & 1 deletion third_party/packages/flutter_svg_test/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: flutter_svg_test
description: A testing library which makes it easy to test flutter_svg. Built to be used with the flutter_svg package.
repository: https://github.com/flutter/packages/tree/main/third_party/packages/flutter_svg_test
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_svg%22
version: 1.0.2
version: 1.0.3

environment:
sdk: ^3.4.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:http/http.dart' as http;
void main() {
group('finds', () {
group('with bytesLoader', () {
// #docregion ByLoader
testWidgets('asset svg', (WidgetTester widgetTester) async {
final SvgPicture asset = SvgPicture.asset('test/flutter_logo.svg');
await widgetTester.pumpWidget(
Expand All @@ -22,6 +23,7 @@ void main() {

expect(find.svg(asset.bytesLoader), findsOneWidget);
});
// #enddocregion ByLoader

testWidgets('network svg', (WidgetTester widgetTester) async {
final http.Client fakeClient = _FakeHttpClient();
Expand Down Expand Up @@ -57,6 +59,7 @@ void main() {
});
});

// #docregion ByPath
testWidgets('asset svg with path', (WidgetTester widgetTester) async {
const String svgPath = 'test/flutter_logo.svg';
await widgetTester.pumpWidget(
Expand All @@ -68,6 +71,7 @@ void main() {

expect(find.svgAssetWithPath(svgPath), findsOneWidget);
});
// #enddocregion ByPath

testWidgets('network svg with url', (WidgetTester widgetTester) async {
const String svgUri = 'svg.dart';
Expand All @@ -76,7 +80,7 @@ void main() {
expect(find.svgNetworkWithUrl(svgUri), findsOneWidget);
});

testWidgets('file svg wit path', (WidgetTester widgetTester) async {
testWidgets('file svg with path', (WidgetTester widgetTester) async {
const String svgPath = 'test/flutter_logo.svg';

await widgetTester.pumpWidget(SvgPicture.file(File(svgPath)));
Expand Down

0 comments on commit e6932b7

Please sign in to comment.