Google is committed to advancing racial equity for Black communities. See how.

FIDL Dart packages

Prerequisites

This tutorial builds on the Compiling FIDL tutorial. For more information on other FIDL tutorials, see the Overview.

Overview

This tutorial details how to use FIDL from Dart by creating a unit test that you can use as a "playground" for exploring the Dart bindings.

This document covers how to complete the following tasks:

The example code is located in your Fuchsia checkout in //topaz/examples/fidl/fidl_packages/. If you want to write all the code as you follow this tutorial, you can remove the example code:

rm -r topaz/examples/fidl/fidl_packages/*

Relative paths in the rest of the tutorial will be relative to this directory.

Write a Dart host test

  1. Add a dummy test to test/types_test.dart:

    import 'package:test/test.dart';
    
    void main() {
      test('dummy', () {
        expect(1 + 1, equals(2));
      });
    }
    
  2. Define a dart_test and then create a depencency on the test through the $host_toolchain. To do this, add the following to BUILD.gn:

    import("//build/dart/test.gni")
    
    
     dart_test("fidl-example-dart-test") {
       sources = [ "types_test.dart" ]
       deps = [ "//third_party/dart-pkg/pub/test" ]
     }
    
    group("fidl_packages") {
      testonly = true
      deps = [ ":fidl-example-dart-test($host_toolchain)" ]
    }
    
  3. Create an empty pubspec file at pubspec.yaml:

    # Copyright 2020 The Fuchsia Authors. All rights reserved.
    # Use of this source code is governed by a BSD-style license that can be
    # found in the LICENSE file.
    
    
  4. (Optional) Create an analysis configuration file at analysis_options.yaml. You can reuse the common Fuchsia analysis configuration:

    # Copyright 2018 The Fuchsia Authors. All rights reserved.
    # Use of this source code is governed by a BSD-style license that can be
    # found in the LICENSE file.
    
    include: ../../../tools/analysis_options.yaml
    
    
  5. Run the empty test suite:

    fx set core.x64 --with //topaz/examples/fidl/fidl_packages
    fx test -vo fidl-example-dart-test
    

    You should see test output for the dummy test that was added.

Add the Dart FIDL bindings as a dependency

For each FIDL library declaration, including the one in Compiling FIDL, a Dart package containing bindings code for that library is generated under the original target name.

Add a dependency on the Dart bindings by referencing this generated crate. The new dart_test target should look like:

dart_test("fidl-example-dart-test") {
  sources = [ "types_test.dart" ]
  deps = [
    "//examples/fidl/fuchsia.examples",
    "//third_party/dart-pkg/pub/test",
  ]
}

(Optional) To view the newly generated bindings:

  1. Rebuild using fx build.
  2. Change to the generated files directory: out/default/dartlang/gen/examples/fidl/fuchsia.examples/fuchsia.examples_package. The code is generated into lib/fidl_async.dart and lib/fidl_test.dart. You may need to change out/default if you have set a different build output directory. You can check your build output directory with cat .fx-build-dir.

For more information on how to find generated bindings code, see Viewing generated bindings code.

Import the FIDL Dart package into your project

To import the package, add the following import statement to the top of the types_test.dart file:

import 'package:fidl_fuchsia_examples/fidl_async.dart' as fidl_examples;

In the Fuchsia tree, FIDL package imports are often aliased to fidl_[library] for readability.

Inspect and use the generated bindings code

You can now write some tests by referring to the generated code. For more information on the bindings, see Dart Bindings Reference.

To get started, you can also use some example code. You can add the following tests inside main():

test('bits', () {
  expect(fidl_examples.FileMode.$none.$value, equals(0));
  expect(fidl_examples.FileMode.read.$value, equals(1));
  final readWrite =
      fidl_examples.FileMode.read | fidl_examples.FileMode.write;
  expect(readWrite.toString(), 'FileMode.read | FileMode.write');
});

test('enums', () {
  final museum = fidl_examples.LocationType.museum;
  expect(fidl_examples.LocationType(1), equals(museum));
  expect(fidl_examples.LocationType.$valueOf('museum'), equals(museum));
  expect(museum.toString(), 'LocationType.museum');
});

test('structs', () {
  final withDefaultName = fidl_examples.Color(id: 0);
  expect(withDefaultName.name, equals('red'));
  expect(withDefaultName.$fields, equals([0, 'red']));

  final blue = fidl_examples.Color(id: 1, name: 'blue');
  expect(blue == withDefaultName, equals(false));
  expect(blue.toString(), 'Color(id: 1, name: blue)');

  final deepBlue = fidl_examples.Color.clone(blue, name: 'deep blue');
  expect(deepBlue.id, equals(1));
  expect(blue == deepBlue, equals(false));
});

test('unions', () {
  final intVal = fidl_examples.JsonValue.withIntValue(1);
  expect(intVal.$tag, equals(fidl_examples.JsonValueTag.intValue));
  expect(intVal.intValue, equals(1));
  expect(
      intVal == fidl_examples.JsonValue.withStringValue('1'), equals(false));

  expect(intVal.toString(), 'JsonValue.intValue(1)');
});

test('tables', () {
  final user = fidl_examples.User();
  expect(user.age, equals(null));
  expect(user.name, equals(null));

  final fuchsia = fidl_examples.User(age: 100, name: 'fuchsia');
  expect(fuchsia.$fields, equals({2: 100, 3: 'fuchsia'}));
  expect(user == fuchsia, equals(false));
});

To rebuild and rerun the tests, run:

fx test -vo fidl-example-dart-test