<commit_before>// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// See //dev/devicelab/bin/tasks/flutter_gallery__memory_nav.dart

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_gallery/gallery/app.dart' show GalleryApp;
import 'package:flutter_test/flutter_test.dart';

Future<void> endOfAnimation() async {
  do {
    await SchedulerBinding.instance.endOfFrame;
  } while (SchedulerBinding.instance.hasScheduledFrame);
}

Rect boundsFor(WidgetController controller, Finder item) {
  final RenderBox box = controller.renderObject<RenderBox>(item);
  return box.localToGlobal(Offset.zero) & box.size;
}

Future<void> main() async {
  final Completer<void> ready = Completer<void>();
  runApp(GestureDetector(
    onTap: () {
      debugPrint('Received tap.');
      ready.complete();
    },
    behavior: HitTestBehavior.opaque,
    child: const IgnorePointer(
      ignoring: true,
      child: GalleryApp(testMode: true),
    ),
  ));
  await SchedulerBinding.instance.endOfFrame;
  await Future<void>.delayed(const Duration(milliseconds: 50));
  debugPrint('==== MEMORY BENCHMARK ==== READY ====');

  await ready.future;
  debugPrint('Continuing...');

  // remove onTap handler, enable pointer events for app
  runApp(GestureDetector(
    child: const IgnorePointer(
      ignoring: false,
      child: GalleryApp(testMode: true),
    ),
  ));
  await SchedulerBinding.instance.endOfFrame;

  final WidgetController controller = LiveWidgetController(WidgetsBinding.instance);

  debugPrint('Navigating...');
  await controller.tap(find.text('Material'));
  await Future<void>.delayed(const Duration(milliseconds: 150));
  final Finder demoList = find.byKey(const Key('GalleryDemoList'));
  final Finder demoItem = find.text('Text fields');
  do {
    await controller.drag(demoList, const Offset(0.0, -300.0));
    await Future<void>.delayed(const Duration(milliseconds: 20));
  } while (!demoItem.precache());

  // Ensure that the center of the "Text fields" item is visible
  // because that's where we're going to tap
  final Rect demoItemBounds = boundsFor(controller, demoItem);
  final Rect demoListBounds = boundsFor(controller, demoList);
  if (!demoListBounds.contains(demoItemBounds.center)) {
    await controller.drag(demoList, Offset(0.0, demoListBounds.center.dy - demoItemBounds.center.dy));
    await endOfAnimation();
  }

  for (int iteration = 0; iteration < 15; iteration += 1) {
    debugPrint('Tapping... (iteration $iteration)');
    await controller.tap(demoItem);
    await endOfAnimation();
    debugPrint('Backing out...');
    await controller.tap(find.byTooltip('Back'));
    await endOfAnimation();
  }

  debugPrint('==== MEMORY BENCHMARK ==== DONE ====');
}
<commit_msg>Add a delay to the Gallery navigation memory test to give Dart an opportunity to GC (#23250)<commit_after>// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// See //dev/devicelab/bin/tasks/flutter_gallery__memory_nav.dart

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_gallery/gallery/app.dart' show GalleryApp;
import 'package:flutter_test/flutter_test.dart';

Future<void> endOfAnimation() async {
  do {
    await SchedulerBinding.instance.endOfFrame;
  } while (SchedulerBinding.instance.hasScheduledFrame);
}

Rect boundsFor(WidgetController controller, Finder item) {
  final RenderBox box = controller.renderObject<RenderBox>(item);
  return box.localToGlobal(Offset.zero) & box.size;
}

Future<void> main() async {
  final Completer<void> ready = Completer<void>();
  runApp(GestureDetector(
    onTap: () {
      debugPrint('Received tap.');
      ready.complete();
    },
    behavior: HitTestBehavior.opaque,
    child: const IgnorePointer(
      ignoring: true,
      child: GalleryApp(testMode: true),
    ),
  ));
  await SchedulerBinding.instance.endOfFrame;
  await Future<void>.delayed(const Duration(milliseconds: 50));
  debugPrint('==== MEMORY BENCHMARK ==== READY ====');

  await ready.future;
  debugPrint('Continuing...');

  // remove onTap handler, enable pointer events for app
  runApp(GestureDetector(
    child: const IgnorePointer(
      ignoring: false,
      child: GalleryApp(testMode: true),
    ),
  ));
  await SchedulerBinding.instance.endOfFrame;

  final WidgetController controller = LiveWidgetController(WidgetsBinding.instance);

  debugPrint('Navigating...');
  await controller.tap(find.text('Material'));
  await Future<void>.delayed(const Duration(milliseconds: 150));
  final Finder demoList = find.byKey(const Key('GalleryDemoList'));
  final Finder demoItem = find.text('Text fields');
  do {
    await controller.drag(demoList, const Offset(0.0, -300.0));
    await Future<void>.delayed(const Duration(milliseconds: 20));
  } while (!demoItem.precache());

  // Ensure that the center of the "Text fields" item is visible
  // because that's where we're going to tap
  final Rect demoItemBounds = boundsFor(controller, demoItem);
  final Rect demoListBounds = boundsFor(controller, demoList);
  if (!demoListBounds.contains(demoItemBounds.center)) {
    await controller.drag(demoList, Offset(0.0, demoListBounds.center.dy - demoItemBounds.center.dy));
    await endOfAnimation();
  }

  for (int iteration = 0; iteration < 15; iteration += 1) {
    debugPrint('Tapping... (iteration $iteration)');
    await controller.tap(demoItem);
    await endOfAnimation();
    debugPrint('Backing out...');
    await controller.tap(find.byTooltip('Back'));
    await endOfAnimation();
    await Future<void>.delayed(const Duration(milliseconds: 50));
  }

  debugPrint('==== MEMORY BENCHMARK ==== DONE ====');
}

{'fraction_non_alphanumeric': 0.12997481108312342, 'fraction_numerical': 0.008900083963056256, 'mean_word_length': 4.5046210720887245, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7584625', 'n_tokens_mistral': 1862, 'n_tokens_neox': 1809, 'n_words': 442}