From 15682143b1a8de7fe9c1cf9b89d4c18db6084d43 Mon Sep 17 00:00:00 2001 From: Eemeli Aro Date: Sun, 23 Aug 2020 11:34:14 +0300 Subject: [PATCH] When creating a mapping from a JS Object, drop undefined values (Closes #173) BREAKING CHANGE: When creating a YAML mapping from a JS Object, keys with `undefined` values are not included. This matches the behaviour of `JSON.stringify()`. In all other cases, the handling of `undefined` is unchanged, so e.g. `[1, undefined, 2]` will still result in a sequence of three items, the second of which has a `null` value. This too matches the behaviour of `JSON.stringify()`. Previously, `undefined` object values were mapped to `null`. --- src/tags/failsafe/map.js | 6 ++++-- tests/doc/stringify.js | 32 +++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/tags/failsafe/map.js b/src/tags/failsafe/map.js index 029e11fa..999f5971 100644 --- a/src/tags/failsafe/map.js +++ b/src/tags/failsafe/map.js @@ -7,8 +7,10 @@ function createMap(schema, obj, ctx) { if (obj instanceof Map) { for (const [key, value] of obj) map.items.push(createPair(key, value, ctx)) } else if (obj && typeof obj === 'object') { - for (const key of Object.keys(obj)) - map.items.push(createPair(key, obj[key], ctx)) + for (const key of Object.keys(obj)) { + const value = obj[key] + if (value !== undefined) map.items.push(createPair(key, value, ctx)) + } } if (typeof schema.sortMapEntries === 'function') { map.items.sort(schema.sortMapEntries) diff --git a/tests/doc/stringify.js b/tests/doc/stringify.js index 480b0ad2..76338509 100644 --- a/tests/doc/stringify.js +++ b/tests/doc/stringify.js @@ -2,7 +2,7 @@ import { source } from 'common-tags' import YAML from '../../index.js' -import { Pair } from '../../types.js' +import { Pair, Scalar } from '../../types.js' import { Type, stringifyString } from '../../util.js' for (const [name, version] of [ @@ -715,3 +715,33 @@ describe('Document markers in top-level scalars', () => { expect(YAML.parse(str)).toBe('foo\n%bar\n') }) }) + +describe('undefined values', () => { + test('undefined', () => { + expect(YAML.stringify(undefined)).toBe('\n') + }) + + test('[1, undefined, 2]', () => { + expect(YAML.stringify([1, undefined, 2])).toBe('- 1\n- null\n- 2\n') + }) + + test("{ a: 'A', b: undefined, c: 'C' }", () => { + expect(YAML.stringify({ a: 'A', b: undefined, c: 'C' })).toBe( + 'a: A\nc: C\n' + ) + }) + + test("{ a: 'A', b: Scalar(undefined), c: 'C' }", () => { + const obj = { a: 'A', b: new Scalar(undefined), c: 'C' } + expect(YAML.stringify(obj)).toBe('a: A\nb: null\nc: C\n') + }) + + test("Map { 'a' => 'A', 'b' => undefined, 'c' => 'C' }", () => { + const map = new Map([ + ['a', 'A'], + ['b', undefined], + ['c', 'C'] + ]) + expect(YAML.stringify(map)).toBe('a: A\nb: null\nc: C\n') + }) +})