diff options
Diffstat (limited to 'spec/frontend/lib/utils/yaml_spec.js')
-rw-r--r-- | spec/frontend/lib/utils/yaml_spec.js | 105 |
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()); + }); + }); + }); +}); |