// Copyright (c) 2018, 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.

/// Unit tests for lib/src/experiment_options.dart.
library dartdoc.experiment_options_test;

import 'dart:io';

import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:dartdoc/src/dartdoc_options.dart';
import 'package:dartdoc/src/experiment_options.dart';
import 'package:test/test.dart';

void main() {
  DartdocOptionSet experimentOptions;
  Directory emptyTempDir;
  ExperimentalFeature defaultOnNotExpired, defaultOffNotExpired;
  ExperimentalFeature defaultOnExpired, defaultOffExpired;

  setUp(() async {
    experimentOptions = await DartdocOptionSet.fromOptionGenerators(
        'dartdoc', [createExperimentOptions]);
  });

  setUpAll(() {
    emptyTempDir =
        Directory.systemTemp.createTempSync('experiment_options_test_empty');
    // We don't test our functionality at all unless ExperimentStatus has at least
    // one of these.  TODO(jcollins-g): make analyzer+dartdoc connection
    // more amenable to testing.
    defaultOnNotExpired = ExperimentStatus.knownFeatures.values.firstWhere(
        (f) => f.isEnabledByDefault && !f.isExpired,
        orElse: () => null);
    defaultOffNotExpired = ExperimentStatus.knownFeatures.values.firstWhere(
        (f) => !f.isEnabledByDefault && !f.isExpired,
        orElse: () => null);
    assert(defaultOnNotExpired != null || defaultOffNotExpired != null,
        'No experimental options that are not expired found');

    // The "bogus" entries should always exist.
    defaultOnExpired = ExperimentStatus.knownFeatures.values
        .firstWhere((f) => f.isEnabledByDefault && f.isExpired);
    defaultOffExpired = ExperimentStatus.knownFeatures.values
        .firstWhere((f) => !f.isEnabledByDefault && f.isExpired);
  });

  tearDownAll(() {
    emptyTempDir.deleteSync(recursive: true);
  });

  group('Experimental options test', () {
    test('Defaults work for all options', () {
      experimentOptions.parseArguments([]);
      DartdocOptionContext tester =
          new DartdocOptionContext(experimentOptions, emptyTempDir);
      if (defaultOnNotExpired != null) {
        expect(tester.experimentStatus.isEnabled(defaultOnNotExpired), isTrue);
      }
      if (defaultOffNotExpired != null) {
        expect(
            tester.experimentStatus.isEnabled(defaultOffNotExpired), isFalse);
      }
      expect(tester.experimentStatus.isEnabled(defaultOnExpired), isTrue);
      expect(tester.experimentStatus.isEnabled(defaultOffExpired), isFalse);
    });

    test('Overriding defaults works via args', () {
      // Set all arguments to non-default values.
      experimentOptions.parseArguments([
        '--enable-experiment',
        '${defaultOffNotExpired?.disableString},${defaultOnNotExpired?.disableString},${defaultOnExpired.disableString},${defaultOffExpired.enableString}'
      ]);
      DartdocOptionContext tester =
          new DartdocOptionContext(experimentOptions, emptyTempDir);
      if (defaultOnNotExpired != null) {
        expect(tester.experimentStatus.isEnabled(defaultOnNotExpired), isFalse);
      }
      if (defaultOffNotExpired != null) {
        expect(
            tester.experimentStatus.isEnabled(defaultOffNotExpired), isFalse);
      }
      expect(tester.experimentStatus.isEnabled(defaultOnExpired), isTrue);
      expect(tester.experimentStatus.isEnabled(defaultOffExpired), isFalse);
    });
  });
}
