blob: 624a3030f449d2ec248a7be709d2af06db982352 [file] [log] [blame] [edit]
// 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:source_span/source_span.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');
});
test('merged order directly from yaml', () {
YamlMap loadYaml(String content) {
return loadYamlNode(content) as YamlMap;
}
var aYaml = """foo:
a: bar""";
var bYaml = """foo:
b: baz""";
var merge1Value = mergeYamlMaps(
loadYaml(bYaml),
loadYaml(aYaml),
).valueAt("foo").toString();
for (int i = 0; i < 100; i++) {
var merge2Value = mergeYamlMaps(
loadYaml(bYaml),
loadYaml(aYaml),
).valueAt("foo").toString();
expect(merge2Value, merge1Value);
}
});
test('merged w/promotion order directly from yaml', () {
YamlMap loadYaml(String content) {
return loadYamlNode(content) as YamlMap;
}
var aYaml = """foo:
- a
- b
- c
- d""";
var bYaml = """foo:
b: true""";
var merge1Value = mergeYamlMaps(
loadYaml(bYaml),
loadYaml(aYaml),
).valueAt("foo").toString();
for (int i = 0; i < 100; i++) {
var merge2Value = mergeYamlMaps(
loadYaml(bYaml),
loadYaml(aYaml),
).valueAt("foo").toString();
expect(merge2Value, merge1Value);
}
});
});
});
}
final Merger merger = Merger();
Object merge(Object o1, Object o2) =>
merger.merge(wrap(o1), wrap(o2)).valueOrThrow;
YamlMap mergeYamlMaps(YamlMap defaults, YamlMap overrides) =>
Merger().mergeMap(defaults, overrides);
YamlNode wrap(Object? value) {
if (value is List) {
var wrappedElements = value.map((e) => wrap(e)).toList();
return YamlList.internal(
wrappedElements,
_FileSpanMock.instance,
CollectionStyle.BLOCK,
);
} else if (value is Map) {
Map<dynamic, YamlNode> wrappedEntries = <dynamic, YamlNode>{};
value.forEach((k, v) {
wrappedEntries[wrap(k)] = wrap(v);
});
return YamlMap.internal(
wrappedEntries,
_FileSpanMock.instance,
CollectionStyle.BLOCK,
);
} else {
return YamlScalar.internal(
value,
ScalarEvent(_FileSpanMock.instance, '', ScalarStyle.PLAIN),
);
}
}
class _FileSpanMock implements FileSpan {
static final FileSpan instance = _FileSpanMock();
@override
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}