<commit_before>import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:provider/provider.dart';
import 'package:provider/src/provider.dart';

import 'common.dart';

class Context extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

BuildContext get context => find.byType(Context).evaluate().single;

T of<T>([BuildContext c]) => Provider.of<T>(c ?? context, listen: false);

void main() {
  testWidgets('Provider.of(listen: false) outside of build works when it loads a provider', (tester) async {
    final notifier = ValueNotifier(42);
    await tester.pumpWidget(
      MultiProvider(
        providers: [
          ValueListenableProvider.value(value: notifier),
          ProxyProvider<int, String>(update: (a, b, c) => '$b'),
        ],
        child: Context(),
      ),
    );

    expect(Provider.of<String>(context, listen: false), '42');

    notifier.value = 21;
    await tester.pump();

    expect(Provider.of<String>(context, listen: false), '21');
  });
  testWidgets('new value is available in didChangeDependencies', (tester) async {
    final didChangeDependencies = ValueBuilderMock<int>();
    final build = ValueBuilderMock<int>();

    await tester.pumpWidget(
      InheritedProvider.value(
        value: 0,
        child: Test<int>(
          didChangeDependencies: didChangeDependencies,
          build: build,
        ),
      ),
    );
    verify(didChangeDependencies(argThat(isNotNull), 0)).called(1);
    verify(build(argThat(isNotNull), 0)).called(1);

    verifyNoMoreInteractions(didChangeDependencies);
    verifyNoMoreInteractions(build);

    await tester.pumpWidget(
      InheritedProvider.value(
        value: 1,
        child: Test<int>(
          didChangeDependencies: didChangeDependencies,
          build: build,
        ),
      ),
    );
    verify(didChangeDependencies(argThat(isNotNull), 1)).called(1);
    verify(build(argThat(isNotNull), 1)).called(1);
    verifyNoMoreInteractions(didChangeDependencies);
    verifyNoMoreInteractions(build);
  });
  testWidgets('provider.of throws if listen:true outside of the widget tree', (tester) async {
    await tester.pumpWidget(
      InheritedProvider<int>.value(
        value: 42,
        child: Context(),
      ),
    );

    expect(
      () => Provider.of<int>(context),
      throwsA(
        isA<AssertionError>().having(
          (source) => source.toString(),
          'toString',
          endsWith('''
Tried to listen to a value exposed with provider, from outside of the widget tree.

This is likely caused by an event handler (like a button's onPressed) that called
Provider.of without passing `listen: false`.

To fix, write:
Provider.of<int>(context, listen: false);

It is unsupported because may pointlessly rebuild the widget associated to the
event handler, when the widget tree doesn't care about the value.

The context used was: Context
'''),
        ),
      ),
    );

    expect(Provider.of<int>(context, listen: false), equals(42));
  });

  testWidgets('Provider throws if no child is provided with default constructor', (tester) async {
    await tester.pumpWidget(
      InheritedProvider<int>(
        create: (_) => 42,
      ),
    );

    expect(
      tester.takeException(),
      isA<AssertionError>().having(
        (source) => source.toString(),
        'toString',
        endsWith('InheritedProvider<int> used outside of MultiProvider must specify a child'),
      ),
    );
  });

  testWidgets('Provider throws if no child is provided with value constructor', (tester) async {
    await tester.pumpWidget(
      InheritedProvider<int>.value(
        value: 42,
      ),
    );

    expect(
      tester.takeException(),
      isA<AssertionError>().having(
        (source) => source.toString(),
        'toString',
        endsWith('InheritedProvider<int> used outside of MultiProvider must specify a child'),
      ),
    );
  });
  group('diagnostics', () {
    testWidgets('InheritedProvider.value', (tester) async {
      await tester.pumpWidget(
        InheritedProvider<int>.value(
          value: 42,
          startListening: (_, __) => throw Error(),
          child: Container(),
        ),
      );

      final rootElement = tester.allElements.first;

      expect(
        rootElement.toString(),
        contains('InheritedProvider<int>(value: 42)'),
      );

      await tester.pumpWidget(
        InheritedProvider<int>.value(
          value: 42,
          startListening: (_, __) => () {},
          child: const TextOf<int>(),<commit_msg>add tests for DeferredInheritedProvider<commit_after>import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:provider/provider.dart';
import 'package:provider/src/provider.dart';

import 'common.dart';

class Context extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

BuildContext get context => find.byType(Context).evaluate().single;

T of<T>([BuildContext c]) => Provider.of<T>(c ?? context, listen: false);

void main() {
  testWidgets('Provider.of(listen: false) outside of build works when it loads a provider', (tester) async {
    final notifier = ValueNotifier(42);
    await tester.pumpWidget(
      MultiProvider(
        providers: [
          ValueListenableProvider.value(value: notifier),
          ProxyProvider<int, String>(update: (a, b, c) => '$b'),
        ],
        child: Context(),
      ),
    );

    expect(Provider.of<String>(context, listen: false), '42');

    notifier.value = 21;
    await tester.pump();

    expect(Provider.of<String>(context, listen: false), '21');
  });
  testWidgets('new value is available in didChangeDependencies', (tester) async {
    final didChangeDependencies = ValueBuilderMock<int>();
    final build = ValueBuilderMock<int>();

    await tester.pumpWidget(
      InheritedProvider.value(
        value: 0,
        child: Test<int>(
          didChangeDependencies: didChangeDependencies,
          build: build,
        ),
      ),
    );
    verify(didChangeDependencies(argThat(isNotNull), 0)).called(1);
    verify(build(argThat(isNotNull), 0)).called(1);

    verifyNoMoreInteractions(didChangeDependencies);
    verifyNoMoreInteractions(build);

    await tester.pumpWidget(
      InheritedProvider.value(
        value: 1,
        child: Test<int>(
          didChangeDependencies: didChangeDependencies,
          build: build,
        ),
      ),
    );
    verify(didChangeDependencies(argThat(isNotNull), 1)).called(1);
    verify(build(argThat(isNotNull), 1)).called(1);
    verifyNoMoreInteractions(didChangeDependencies);
    verifyNoMoreInteractions(build);
  });
  testWidgets('provider.of throws if listen:true outside of the widget tree', (tester) async {
    await tester.pumpWidget(
      InheritedProvider<int>.value(
        value: 42,
        child: Context(),
      ),
    );

    expect(
      () => Provider.of<int>(context),
      throwsA(
        isA<AssertionError>().having(
          (source) => source.toString(),
          'toString',
          endsWith('''
Tried to listen to a value exposed with provider, from outside of the widget tree.

This is likely caused by an event handler (like a button's onPressed) that called
Provider.of without passing `listen: false`.

To fix, write:
Provider.of<int>(context, listen: false);

It is unsupported because may pointlessly rebuild the widget associated to the
event handler, when the widget tree doesn't care about the value.

The context used was: Context
'''),
        ),
      ),
    );

    expect(Provider.of<int>(context, listen: false), equals(42));
  });

  testWidgets('InheritedProvider throws if no child is provided with default constructor', (tester) async {
    await tester.pumpWidget(
      InheritedProvider<int>(
        create: (_) => 42,
      ),
    );

    expect(
      tester.takeException(),
      isA<AssertionError>().having(
        (source) => source.toString(),
        'toString',
        endsWith('InheritedProvider<int> used outside of MultiProvider must specify a child'),
      ),
    );
  });

  testWidgets('InheritedProvider throws if no child is provided with value constructor', (tester) async {
    await tester.pumpWidget(
      InheritedProvider<int>.value(
        value: 42,
      ),
    );

    expect(
      tester.takeException(),
      isA<AssertionError>().having(
        (source) => source.toString(),
        'toString',
        endsWith('InheritedProvider<int> used outside of MultiProvider must specify a child'),
      ),
    );
  });

  testWidgets('DeferredInheritedProvider throws if no child is provided with default constructor', (tester) async {
    await tester.pumpWidget(
      DeferredInheritedProvider<int, int>(
          create: (_) => 42,
          startListening: (_, __, ___, ____) {
            return () {};
          }),
    );

    expect(
      tester.takeException(),
      isA<AssertionError>().having(
        (source) => source.toString(),
        'toString',
        endsWith('DeferredInheritedProvider<int, int> used outside of MultiProvider must specify a child'),
      ),
    );
  });

  testWidgets('DeferredInheritedProvider throws if no child is provided with value constructor', (tester) async {
    await tester.pumpWidget(
      DeferredInheritedProvider<int, int>.value(
          value: 42,
          startListening: (_, __, ___, ____) {
            return () {};
          }),
    );

    expect(
      tester.takeException(),
      isA<AssertionError>().having(
        (source) => source.toString(),
        'toString',
        endsWith('DeferredInheritedProvider<int, int> used outside of MultiProvider must specify a child'),
      ),
    );
  });
  group('diagnostics', () {
    testWidgets('InheritedProvider.value', (tester) async {
      await tester.pumpWidget(
        InheritedProvider<int>.value(
          value: 42,
          startListening: (_, __) => throw Error(),
          child: Container(),
        ),
      );

      final rootElement = tester.allElements.first;

      expect(
        rootElement.toString(),
        contains('InheritedProvider<int>(value: 42)'),
      );

      await tester.pumpWidget(
        InheritedProvider<int>.value(
          value: 42,
          startListening: (_, __) => () {},
          child: const TextOf<int>(),
{'fraction_non_alphanumeric': 0.12638095238095237, 'fraction_numerical': 0.0064761904761904765, 'mean_word_length': 2.946260804208944, 'pattern_counts': {'":': 0, '<': 57, '<?xml version=': 0, '>': 80, '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': '2116851', 'n_tokens_mistral': 3106, 'n_tokens_neox': 2979, 'n_words': 708}