summaryrefslogtreecommitdiff
path: root/spec/frontend/lib/utils/yaml_spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/lib/utils/yaml_spec.js')
-rw-r--r--spec/frontend/lib/utils/yaml_spec.js105
1 files changed, 105 insertions, 0 deletions
diff --git a/spec/frontend/lib/utils/yaml_spec.js b/spec/frontend/lib/utils/yaml_spec.js
new file mode 100644
index 00000000000..d1ce00130e2
--- /dev/null
+++ b/spec/frontend/lib/utils/yaml_spec.js
@@ -0,0 +1,105 @@
+import { Document, parseDocument } from 'yaml';
+import { merge } from '~/lib/utils/yaml';
+
+// Mock data for Comments on pairs
+const COMMENTS_ON_PAIRS_SOURCE = `foo:
+ # barbaz
+ bar: baz
+
+ # bazboo
+ baz: boo
+`;
+
+const COMMENTS_ON_PAIRS_TARGET = `foo:
+ # abcdef
+ abc: def
+ # boobaz
+ boo: baz
+`;
+
+const COMMENTS_ON_PAIRS_EXPECTED = `foo:
+ # abcdef
+ abc: def
+ # boobaz
+ boo: baz
+ # barbaz
+ bar: baz
+
+ # bazboo
+ baz: boo
+`;
+
+// Mock data for Comments on seqs
+const COMMENTS_ON_SEQS_SOURCE = `foo:
+ # barbaz
+ - barbaz
+ # bazboo
+ - baz: boo
+`;
+
+const COMMENTS_ON_SEQS_TARGET = `foo:
+ # abcdef
+ - abcdef
+
+ # boobaz
+ - boobaz
+`;
+
+const COMMENTS_ON_SEQS_EXPECTED = `foo:
+ # abcdef
+ - abcdef
+
+ # boobaz
+ - boobaz
+ # barbaz
+ - barbaz
+ # bazboo
+ - baz: boo
+`;
+
+describe('Yaml utility functions', () => {
+ describe('merge', () => {
+ const getAsNode = (yamlStr) => {
+ return parseDocument(yamlStr).contents;
+ };
+
+ describe('Merge two Nodes', () => {
+ it.each`
+ scenario | source | target | options | expected
+ ${'merge a map'} | ${getAsNode('foo:\n bar: baz\n')} | ${'foo:\n abc: def\n'} | ${undefined} | ${'foo:\n abc: def\n bar: baz\n'}
+ ${'merge a seq'} | ${getAsNode('foo:\n - bar\n')} | ${'foo:\n - abc\n'} | ${undefined} | ${'foo:\n - bar\n'}
+ ${'merge-append seqs'} | ${getAsNode('foo:\n - bar\n')} | ${'foo:\n - abc\n'} | ${{ onSequence: 'append' }} | ${'foo:\n - abc\n - bar\n'}
+ ${'merge-replace a seq'} | ${getAsNode('foo:\n - bar\n')} | ${'foo:\n - abc\n'} | ${{ onSequence: 'replace' }} | ${'foo:\n - bar\n'}
+ ${'override existing paths'} | ${getAsNode('foo:\n bar: baz\n')} | ${'foo:\n bar: boo\n'} | ${undefined} | ${'foo:\n bar: baz\n'}
+ ${'deep maps'} | ${getAsNode('foo:\n bar:\n abc: def\n')} | ${'foo:\n bar:\n baz: boo\n jkl: mno\n'} | ${undefined} | ${'foo:\n bar:\n baz: boo\n abc: def\n jkl: mno\n'}
+ ${'append maps inside seqs'} | ${getAsNode('foo:\n - abc: def\n')} | ${'foo:\n - bar: baz\n'} | ${{ onSequence: 'append' }} | ${'foo:\n - bar: baz\n - abc: def\n'}
+ ${'inexistent paths create new nodes'} | ${getAsNode('foo:\n bar: baz\n')} | ${'abc: def\n'} | ${undefined} | ${'abc: def\nfoo:\n bar: baz\n'}
+ ${'document as source'} | ${parseDocument('foo:\n bar: baz\n')} | ${'foo:\n abc: def\n'} | ${undefined} | ${'foo:\n abc: def\n bar: baz\n'}
+ ${'object as source'} | ${{ foo: { bar: 'baz' } }} | ${'foo:\n abc: def\n'} | ${undefined} | ${'foo:\n abc: def\n bar: baz\n'}
+ ${'comments on pairs'} | ${parseDocument(COMMENTS_ON_PAIRS_SOURCE)} | ${COMMENTS_ON_PAIRS_TARGET} | ${undefined} | ${COMMENTS_ON_PAIRS_EXPECTED}
+ ${'comments on seqs'} | ${parseDocument(COMMENTS_ON_SEQS_SOURCE)} | ${COMMENTS_ON_SEQS_TARGET} | ${{ onSequence: 'append' }} | ${COMMENTS_ON_SEQS_EXPECTED}
+ `('$scenario', ({ source, target, expected, options }) => {
+ const targetDoc = parseDocument(target);
+ merge(targetDoc, source, options);
+ const expectedDoc = parseDocument(expected);
+ expect(targetDoc.toString()).toEqual(expectedDoc.toString());
+ });
+
+ it('type conflict will throw an Error', () => {
+ const sourceDoc = parseDocument('foo:\n bar:\n - baz\n');
+ const targetDoc = parseDocument('foo:\n bar: def\n');
+ expect(() => merge(targetDoc, sourceDoc)).toThrow(
+ 'Type conflict at "foo.bar": Destination node is of type Scalar, the node' +
+ ' to be merged is of type YAMLSeq',
+ );
+ });
+
+ it('merging a collection into an empty doc', () => {
+ const targetDoc = new Document();
+ merge(targetDoc, { foo: { bar: 'baz' } });
+ const expected = parseDocument('foo:\n bar: baz\n');
+ expect(targetDoc.toString()).toEqual(expected.toString());
+ });
+ });
+ });
+});