// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. 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:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_schema.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../../../generated/type_system_base.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(IsKnownTest);
  });
}

@reflectiveTest
class IsKnownTest extends AbstractTypeSystemTest {
  test_dynamic() {
    _checkKnown(dynamicType);
  }

  test_function() {
    _checkKnown(functionTypeNone(returnType: voidNone));

    _checkUnknown(functionTypeNone(returnType: unknownInferredType));

    _checkUnknown(
      functionTypeNone(
        returnType: voidNone,
        formalParameters: [requiredParameter(type: unknownInferredType)],
      ),
    );
  }

  test_interface() {
    _checkKnown(intNone);
    _checkKnown(listNone(intNone));
    _checkUnknown(listNone(unknownInferredType));
  }

  test_never() {
    _checkKnown(neverNone);
  }

  test_null() {
    _checkKnown(nullNone);
  }

  test_record() {
    _checkKnown(recordTypeNone(positionalTypes: [intNone]));

    _checkUnknown(recordTypeNone(positionalTypes: [unknownInferredType]));

    _checkKnown(recordTypeNone(namedTypes: {'x': intNone}));

    _checkUnknown(recordTypeNone(namedTypes: {'x': unknownInferredType}));
  }

  test_unknownInferredType() {
    _checkUnknown(unknownInferredType);
  }

  test_void() {
    _checkKnown(voidNone);
  }

  void _checkKnown(DartType type) {
    expect(UnknownInferredType.isKnown(type), isTrue);
    expect(UnknownInferredType.isUnknown(type), isFalse);
  }

  void _checkUnknown(DartType type) {
    expect(UnknownInferredType.isKnown(type), isFalse);
    expect(UnknownInferredType.isUnknown(type), isTrue);
  }
}
