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

@TestOn('vm')

import 'dart:io';
import 'dart:convert';

import 'package:path/path.dart' as p;
import 'package:test/test.dart';

import 'package:test_descriptor/test_descriptor.dart' as d;

import 'utils.dart';

void main() {
  group("create()", () {
    test('creates a text file', () async {
      await d.file('name.txt', 'contents').create();

      expect(new File(p.join(d.sandbox, 'name.txt')).readAsString(),
          completion(equals('contents')));
    });

    test('creates a binary file', () async {
      await d.file('name.txt', [0, 1, 2, 3]).create();

      expect(new File(p.join(d.sandbox, 'name.txt')).readAsBytes(),
          completion(equals([0, 1, 2, 3])));
    });

    test('fails to create a matcher file', () async {
      expect(d.file('name.txt', contains('foo')).create(),
          throwsUnsupportedError);
    });

    test('overwrites an existing file', () async {
      await d.file('name.txt', 'contents1').create();
      await d.file('name.txt', 'contents2').create();

      expect(new File(p.join(d.sandbox, 'name.txt')).readAsString(),
          completion(equals('contents2')));
    });
  });

  group("validate()", () {
    test('succeeds if the filesystem matches a text descriptor', () async {
      await new File(p.join(d.sandbox, 'name.txt')).writeAsString('contents');
      await d.file('name.txt', 'contents').validate();
    });

    test('succeeds if the filesystem matches a binary descriptor', () async {
      await new File(p.join(d.sandbox, 'name.txt')).writeAsBytes([0, 1, 2, 3]);
      await d.file('name.txt', [0, 1, 2, 3]).validate();
    });

    test('succeeds if the filesystem matches a text matcher', () async {
      await new File(p.join(d.sandbox, 'name.txt')).writeAsString('contents');
      await d.file('name.txt', contains('ent')).validate();
    });

    test('succeeds if the filesystem matches a binary matcher', () async {
      await new File(p.join(d.sandbox, 'name.txt')).writeAsBytes([0, 1, 2, 3]);
      await new d.FileDescriptor.binaryMatcher('name.txt', contains(2))
          .validate();
    });

    test("fails if the text contents don't match", () async {
      await new File(p.join(d.sandbox, 'name.txt')).writeAsString('wrong');

      expect(d.file('name.txt', 'contents').validate(),
          throwsA(toString(startsWith('File "name.txt" should contain:'))));
    });

    test("fails if the binary contents don't match", () async {
      await new File(p.join(d.sandbox, 'name.txt')).writeAsBytes([5, 4, 3, 2]);

      expect(d.file('name.txt', [0, 1, 2, 3]).validate(),
          throwsA(toString(equals(
              'File "name.txt" didn\'t contain the expected binary data.'))));
    });

    test("fails if the text contents don't match the matcher", () async {
      await new File(p.join(d.sandbox, 'name.txt')).writeAsString('wrong');

      expect(d.file('name.txt', contains('ent')).validate(),
          throwsA(toString(startsWith(
              'Invalid contents for file "name.txt":'))));
    });

    test("fails if the binary contents don't match the matcher", () async {
      await new File(p.join(d.sandbox, 'name.txt')).writeAsBytes([5, 4, 3, 2]);

      expect(
          new d.FileDescriptor.binaryMatcher('name.txt', contains(1))
              .validate(),
          throwsA(toString(startsWith(
              'Invalid contents for file "name.txt":'))));
    });

    test("fails if there's no file", () {
      expect(d.file('name.txt', 'contents').validate(),
          throwsA(toString(equals('File not found: "name.txt".'))));
    });
  });

  group("reading", () {
    test("read() returns the contents of a text file as a string", () {
      expect(d.file('name.txt', 'contents').read(),
          completion(equals('contents')));
    });

    test("read() returns the contents of a binary file as a string", () {
      expect(d.file('name.txt', [0x68, 0x65, 0x6c, 0x6c, 0x6f]).read(),
          completion(equals('hello')));
    });

    test("read() fails for a matcher file", () {
      expect(d.file('name.txt', contains('hi')).read,
          throwsUnsupportedError);
    });

    test("readAsBytes() returns the contents of a text file as a byte stream",
        () {
      expect(UTF8.decodeStream(d.file('name.txt', 'contents').readAsBytes()),
          completion(equals('contents')));
    });

    test("readAsBytes() returns the contents of a binary file as a byte stream",
        () {
      expect(byteStreamToList(d.file('name.txt', [0, 1, 2, 3]).readAsBytes()),
          completion(equals([0, 1, 2, 3])));
    });

    test("readAsBytes() fails for a matcher file", () {
      expect(d.file('name.txt', contains('hi')).readAsBytes,
          throwsUnsupportedError);
    });
  });
}
