// Copyright 2014 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/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('Directionality', (WidgetTester tester) async {
    final log = <TextDirection>[];
    final Widget inner = Builder(
      builder: (BuildContext context) {
        log.add(Directionality.of(context));
        return const Placeholder();
      },
    );
    await tester.pumpWidget(Directionality(textDirection: TextDirection.ltr, child: inner));
    expect(log, <TextDirection>[TextDirection.ltr]);
    await tester.pumpWidget(Directionality(textDirection: TextDirection.ltr, child: inner));
    expect(log, <TextDirection>[TextDirection.ltr]);
    await tester.pumpWidget(Directionality(textDirection: TextDirection.rtl, child: inner));
    expect(log, <TextDirection>[TextDirection.ltr, TextDirection.rtl]);
    await tester.pumpWidget(Directionality(textDirection: TextDirection.rtl, child: inner));
    expect(log, <TextDirection>[TextDirection.ltr, TextDirection.rtl]);
    await tester.pumpWidget(Directionality(textDirection: TextDirection.ltr, child: inner));
    expect(log, <TextDirection>[TextDirection.ltr, TextDirection.rtl, TextDirection.ltr]);
  });

  testWidgets('Directionality default', (WidgetTester tester) async {
    var good = false;
    await tester.pumpWidget(
      Builder(
        builder: (BuildContext context) {
          expect(Directionality.maybeOf(context), isNull);
          good = true;
          return const Placeholder();
        },
      ),
    );
    expect(good, isTrue);
  });

  testWidgets('Directionality.maybeOf', (WidgetTester tester) async {
    final GlobalKey hasDirectionality = GlobalKey();
    final GlobalKey noDirectionality = GlobalKey();
    await tester.pumpWidget(
      Container(
        key: noDirectionality,
        child: Directionality(
          textDirection: TextDirection.rtl,
          child: Container(key: hasDirectionality),
        ),
      ),
    );
    expect(Directionality.maybeOf(noDirectionality.currentContext!), isNull);
    expect(Directionality.maybeOf(hasDirectionality.currentContext!), TextDirection.rtl);
  });

  testWidgets('Directionality.of', (WidgetTester tester) async {
    final GlobalKey hasDirectionality = GlobalKey();
    final GlobalKey noDirectionality = GlobalKey();
    await tester.pumpWidget(
      Container(
        key: noDirectionality,
        child: Directionality(
          textDirection: TextDirection.rtl,
          child: Container(key: hasDirectionality),
        ),
      ),
    );
    expect(
      () => Directionality.of(noDirectionality.currentContext!),
      throwsA(
        isAssertionError.having(
          (AssertionError e) => e.message,
          'message',
          contains('No Directionality widget found.'),
        ),
      ),
    );
    expect(Directionality.of(hasDirectionality.currentContext!), TextDirection.rtl);
  });
}
