// Copyright (c) 2017, 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_plugin/protocol/protocol_generated.dart';
import 'package:analyzer_plugin/utilities/subscriptions/subscription_manager.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

void main() {
  defineReflectiveTests(SubscriptionManagerTest);
}

@reflectiveTest
class SubscriptionManagerTest {
  SubscriptionManager manager = new SubscriptionManager();

  String fooPath = '/project/lib/foo.dart';
  String barPath = '/project/lib/bar.dart';
  String bazPath = '/project/lib/baz.dart';

  test_hasSubscriptionForFile_differentSubscription() {
    manager.setSubscriptions({
      AnalysisService.NAVIGATION: [barPath]
    });
    expect(manager.hasSubscriptionForFile(fooPath, AnalysisService.HIGHLIGHTS),
        isFalse);
  }

  test_hasSubscriptionForFile_hasSubscription() {
    manager.setSubscriptions({
      AnalysisService.HIGHLIGHTS: [fooPath]
    });
    expect(manager.hasSubscriptionForFile(fooPath, AnalysisService.HIGHLIGHTS),
        isTrue);
  }

  test_hasSubscriptionForFile_noSubscription() {
    expect(manager.hasSubscriptionForFile(fooPath, AnalysisService.HIGHLIGHTS),
        isFalse);
  }

  test_servicesForFile() {
    expect(manager.servicesForFile('/project/lib/test.dart'), hasLength(0));
  }

  test_setSubscriptions() {
    //
    // Set the initial set of subscriptions.
    //
    Map<String, List<AnalysisService>> newSubscriptions =
        manager.setSubscriptions({
      AnalysisService.HIGHLIGHTS: [fooPath, barPath],
      AnalysisService.NAVIGATION: [fooPath]
    });

    expect(
        manager.servicesForFile(fooPath),
        unorderedEquals(
            [AnalysisService.HIGHLIGHTS, AnalysisService.NAVIGATION]));
    expect(manager.servicesForFile(barPath),
        unorderedEquals([AnalysisService.HIGHLIGHTS]));
    expect(manager.servicesForFile(bazPath), hasLength(0));

    expect(
        newSubscriptions[fooPath],
        unorderedEquals(
            [AnalysisService.HIGHLIGHTS, AnalysisService.NAVIGATION]));
    expect(newSubscriptions[barPath],
        unorderedEquals([AnalysisService.HIGHLIGHTS]));
    //
    // Update the subscriptions.
    //
    newSubscriptions = manager.setSubscriptions({
      AnalysisService.HIGHLIGHTS: [bazPath, barPath],
      AnalysisService.NAVIGATION: [barPath]
    });

    expect(manager.servicesForFile(fooPath), hasLength(0));
    expect(
        manager.servicesForFile(barPath),
        unorderedEquals(
            [AnalysisService.HIGHLIGHTS, AnalysisService.NAVIGATION]));
    expect(manager.servicesForFile(bazPath),
        unorderedEquals([AnalysisService.HIGHLIGHTS]));

    expect(newSubscriptions[barPath],
        unorderedEquals([AnalysisService.NAVIGATION]));
    expect(newSubscriptions[bazPath],
        unorderedEquals([AnalysisService.HIGHLIGHTS]));
  }
}
