blob: ca6054fd7dd4b214fe4fc9e7645df841b2d5a83a [file] [log] [blame]
// Copyright (c) 2015, 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/src/util/yaml.dart';
import 'package:test/test.dart';
import 'package:yaml/src/event.dart';
import 'package:yaml/yaml.dart';
main() {
group('yaml', () {
group('merge', () {
test('map', () {
expect(
merge({
'one': true,
'two': false,
'three': {
'nested': {'four': true, 'six': true}
}
}, {
'three': {
'nested': {'four': false, 'five': true},
'five': true
},
'seven': true
}),
equals(wrap({
'one': true,
'two': false,
'three': {
'nested': {'four': false, 'five': true, 'six': true},
'five': true
},
'seven': true
})));
});
test('list', () {
expect(merge([1, 2, 3], [2, 3, 4, 5]), equals(wrap([1, 2, 3, 4, 5])));
});
test('list w/ promotion', () {
expect(
merge(['one', 'two', 'three'], {'three': false, 'four': true}),
equals(wrap(
{'one': true, 'two': true, 'three': false, 'four': true})));
expect(merge({'one': false, 'two': false}, ['one', 'three']),
equals(wrap({'one': true, 'two': false, 'three': true})));
});
test('map w/ list promotion', () {
var map1 = {
'one': ['a', 'b', 'c']
};
var map2 = {
'one': {'a': true, 'b': false}
};
var map3 = {
'one': {'a': true, 'b': false, 'c': true}
};
expect(merge(map1, map2), wrap(map3));
});
test('map w/ no promotion', () {
var map1 = {
'one': ['a', 'b', 'c']
};
var map2 = {
'one': {'a': 'foo', 'b': 'bar'}
};
var map3 = {
'one': {'a': 'foo', 'b': 'bar'}
};
expect(merge(map1, map2), wrap(map3));
});
test('map w/ no promotion (2)', () {
var map1 = {
'one': {'a': 'foo', 'b': 'bar'}
};
var map2 = {
'one': ['a', 'b', 'c']
};
var map3 = {
'one': ['a', 'b', 'c']
};
expect(merge(map1, map2), wrap(map3));
});
test('object', () {
expect(merge(1, 2), 2);
expect(merge(1, 'foo'), 'foo');
expect(merge({'foo': 1}, 'foo'), 'foo');
});
});
});
}
final Merger merger = new Merger();
bool containsKey(Map<dynamic, YamlNode> map, dynamic key) =>
_getValue(map, key) != null;
void expectEquals(YamlNode actual, YamlNode expected) {
if (expected is YamlScalar) {
expect(actual, new isInstanceOf<YamlScalar>());
expect(expected.value, actual.value);
} else if (expected is YamlList) {
if (actual is YamlList) {
expect(actual.length, expected.length);
List<YamlNode> expectedNodes = expected.nodes;
List<YamlNode> actualNodes = actual.nodes;
for (int i = 0; i < expectedNodes.length; i++) {
expectEquals(actualNodes[i], expectedNodes[i]);
}
} else {
fail('Expected a YamlList, found ${actual.runtimeType}');
}
} else if (expected is YamlMap) {
if (actual is YamlMap) {
expect(actual.length, expected.length);
Map<dynamic, YamlNode> expectedNodes = expected.nodes;
Map<dynamic, YamlNode> actualNodes = actual.nodes;
for (var expectedKey in expectedNodes.keys) {
if (!containsKey(actualNodes, expectedKey)) {
fail('Missing key $expectedKey');
}
}
for (var actualKey in actualNodes.keys) {
if (!containsKey(expectedNodes, actualKey)) {
fail('Extra key $actualKey');
}
}
for (var expectedKey in expectedNodes.keys) {
expectEquals(_getValue(actualNodes, expectedKey),
_getValue(expectedNodes, expectedKey));
}
} else {
fail('Expected a YamlMap, found ${actual.runtimeType}');
}
} else {
fail('Unknown type of node: ${expected.runtimeType}');
}
}
Object merge(Object o1, Object o2) => merger.merge(wrap(o1), wrap(o2)).value;
Object valueOf(Object object) => object is YamlNode ? object.value : object;
YamlNode wrap(Object value) {
if (value is List) {
List wrappedElements = value.map((e) => wrap(e)).toList();
return new YamlList.internal(wrappedElements, null, CollectionStyle.BLOCK);
} else if (value is Map) {
Map<dynamic, YamlNode> wrappedEntries = <dynamic, YamlNode>{};
value.forEach((k, v) {
wrappedEntries[wrap(k)] = wrap(v);
});
return new YamlMap.internal(wrappedEntries, null, CollectionStyle.BLOCK);
} else {
return new YamlScalar.internal(
value, new ScalarEvent(null, '', ScalarStyle.PLAIN));
}
}
YamlNode _getValue(Map map, Object key) {
Object keyValue = valueOf(key);
for (var existingKey in map.keys) {
if (valueOf(existingKey) == keyValue) {
return map[existingKey];
}
}
return null;
}