// Copyright (c) 2014, the Dart project authors.
// Copyright (c) 2006, Kirill Simonov.
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

import 'package:test/test.dart';
import 'package:yaml/src/equality.dart' as equality;
import 'package:yaml/yaml.dart';

/// A matcher that validates that a closure or Future throws a [YamlException].
final Matcher throwsYamlException = throwsA(isA<YamlException>());

/// Returns a matcher that asserts that the value equals [expected].
///
/// This handles recursive loops and considers `NaN` to equal itself.
Matcher deepEquals(Object? expected) => predicate(
    (actual) => equality.deepEquals(actual, expected), 'equals $expected');

/// Constructs a new yaml.YamlMap, optionally from a normal Map.
Map deepEqualsMap([Map? from]) {
  var map = equality.deepEqualsMap<Object?, Object?>();
  if (from != null) map.addAll(from);
  return map;
}

/// Asserts that an error has the given message and starts at the given line/col.
void expectErrorAtLineCol(
    YamlException error, String message, int line, int col) {
  expect(error.message, equals(message));
  expect(error.span!.start.line, equals(line));
  expect(error.span!.start.column, equals(col));
}

/// Asserts that a string containing a single YAML document produces a given
/// value when loaded.
void expectYamlLoads(Object? expected, String source) {
  var actual = loadYaml(cleanUpLiteral(source));
  expect(actual, deepEquals(expected));
}

/// Asserts that a string containing a stream of YAML documents produces a given
/// list of values when loaded.
void expectYamlStreamLoads(List expected, String source) {
  var actual = loadYamlStream(cleanUpLiteral(source));
  expect(actual, deepEquals(expected));
}

/// Asserts that a string containing a single YAML document throws a
/// [YamlException].
void expectYamlFails(String source) {
  expect(() => loadYaml(cleanUpLiteral(source)), throwsYamlException);
}

/// Removes eight spaces of leading indentation from a multiline string.
///
/// Note that this is very sensitive to how the literals are styled. They should
/// be:
///     '''
///     Text starts on own line. Lines up with subsequent lines.
///     Lines are indented exactly 8 characters from the left margin.
///     Close is on the same line.'''
///
/// This does nothing if text is only a single line.
String cleanUpLiteral(String text) {
  var lines = text.split('\n');
  if (lines.length <= 1) return text;

  for (var j = 0; j < lines.length; j++) {
    if (lines[j].length > 8) {
      lines[j] = lines[j].substring(8, lines[j].length);
    } else {
      lines[j] = '';
    }
  }

  return lines.join('\n');
}

/// Indents each line of [text] so that, when passed to [cleanUpLiteral], it
/// will produce output identical to [text].
///
/// This is useful for literals that need to include newlines but can't be
/// conveniently represented as multi-line strings.
String indentLiteral(String text) {
  var lines = text.split('\n');
  if (lines.length <= 1) return text;

  for (var i = 0; i < lines.length; i++) {
    lines[i] = '        ${lines[i]}';
  }

  return lines.join('\n');
}
