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

library usage.common_test;

import 'dart:async';

import 'package:test/test.dart';
import 'package:usage/src/usage_impl.dart';

AnalyticsImplMock createMock({Map<String, dynamic> props}) =>
    new AnalyticsImplMock('UA-0', props: props);

was(Map m, String type) => expect(m['t'], type);
has(Map m, String key) => expect(m[key], isNotNull);
hasnt(Map m, String key) => expect(m[key], isNull);

class AnalyticsImplMock extends AnalyticsImpl {
  MockProperties get mockProperties => properties;
  MockPostHandler get mockPostHandler => postHandler;

  AnalyticsImplMock(String trackingId, {Map<String, dynamic> props})
      : super(trackingId, new MockProperties(props), new MockPostHandler(),
            applicationName: 'Test App', applicationVersion: '0.1');

  Map<String, dynamic> get last => mockPostHandler.last;
}

class MockProperties extends PersistentProperties {
  Map<String, dynamic> props = {};

  MockProperties([Map<String, dynamic> props]) : super('mock') {
    if (props != null) this.props.addAll(props);
  }

  dynamic operator [](String key) => props[key];

  void operator []=(String key, dynamic value) {
    props[key] = value;
  }
}

class MockPostHandler extends PostHandler {
  List<Map<String, dynamic>> sentValues = [];

  Future sendPost(String url, Map<String, dynamic> parameters) {
    sentValues.add(parameters);

    return new Future.value();
  }

  Map<String, dynamic> get last => sentValues.last;
}
