Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use indicator line for props on block collection values of mappings #425

Merged
merged 1 commit into from
Nov 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 43 additions & 16 deletions src/stringify/stringifyPair.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,16 @@ export function stringifyPair(
str += lineComment(str, ctx.indent, commentString(keyComment))
}

let vcb = ''
let valueComment = null
let vsb, vcb, valueComment
if (isNode(value)) {
if (value.spaceBefore) vcb = '\n'
if (value.commentBefore) {
const cs = commentString(value.commentBefore)
vcb += `\n${indentComment(cs, ctx.indent)}`
}
vsb = !!value.spaceBefore
vcb = value.commentBefore
valueComment = value.comment
} else if (value && typeof value === 'object') {
value = doc.createNode(value)
} else {
vsb = false
vcb = null
valueComment = null
if (value && typeof value === 'object') value = doc.createNode(value)
}
ctx.implicitKey = false
if (!explicitKey && !keyComment && isScalar(value))
Expand All @@ -109,7 +108,7 @@ export function stringifyPair(
!value.anchor
) {
// If indentSeq === false, consider '- ' as part of indentation where possible
ctx.indent = ctx.indent.substr(2)
ctx.indent = ctx.indent.substring(2)
}

let valueCommentDone = false
Expand All @@ -120,13 +119,41 @@ export function stringifyPair(
() => (chompKeep = true)
)
let ws = ' '
if (vcb || keyComment) {
if (valueStr === '' && !ctx.inFlow) ws = vcb === '\n' ? '\n\n' : vcb
else ws = `${vcb}\n${ctx.indent}`
if (keyComment || vsb || vcb) {
ws = vsb ? '\n' : ''
if (vcb) {
const cs = commentString(vcb)
ws += `\n${indentComment(cs, ctx.indent)}`
}
if (valueStr === '' && !ctx.inFlow) {
if (ws === '\n') ws = '\n\n'
} else {
ws += `\n${ctx.indent}`
}
} else if (!explicitKey && isCollection(value)) {
const flow = valueStr[0] === '[' || valueStr[0] === '{'
if (!flow || valueStr.includes('\n')) ws = `\n${ctx.indent}`
} else if (valueStr === '' || valueStr[0] === '\n') ws = ''
const vs0 = valueStr[0]
const nl0 = valueStr.indexOf('\n')
const hasNewline = nl0 !== -1
const flow = ctx.inFlow ?? value.flow ?? value.items.length === 0
if (hasNewline || !flow) {
let hasPropsLine = false
if (hasNewline && (vs0 === '&' || vs0 === '!')) {
let sp0 = valueStr.indexOf(' ')
if (
vs0 === '&' &&
sp0 !== -1 &&
sp0 < nl0 &&
valueStr[sp0 + 1] === '!'
) {
sp0 = valueStr.indexOf(' ', sp0 + 1)
}
if (sp0 === -1 || nl0 < sp0) hasPropsLine = true
}
if (!hasPropsLine) ws = `\n${ctx.indent}`
}
} else if (valueStr === '' || valueStr[0] === '\n') {
ws = ''
}
str += ws + valueStr

if (ctx.inFlow) {
Expand Down
154 changes: 142 additions & 12 deletions tests/doc/stringify.js
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,7 @@ foo:
const seq = [{ foo: { bar: { baz } } }, { fe: { fi: { fo: { baz } } } }]
expect(YAML.stringify(seq)).toBe(`- foo:
bar:
baz:
&a1
baz: &a1
a: 1
- fe:
fi:
Expand Down Expand Up @@ -364,6 +363,137 @@ z:
)
})
})

describe('properties on collections in block mapping', () => {
test('explicit tag on block sequence', () => {
const src = source`
key: !tag
- one
- two
`
const doc = YAML.parseDocument(src)
expect(String(doc)).toBe(src)
})
test('explicit tag on block mapping', () => {
const src = source`
key: !tag
one: 1
two: 2
`
const doc = YAML.parseDocument(src)
expect(String(doc)).toBe(src)
})
test('single-line comment on block sequence', () => {
const src = source`
key: #comment
- one
- two
`
const doc = YAML.parseDocument(src)
expect(String(doc)).toBe(source`
key:
#comment
- one
- two
`)
})
test('single-line comment and explicit tag on block sequence', () => {
const src = source`
key: #comment
!tag
- one
- two
`
const doc = YAML.parseDocument(src)
expect(String(doc)).toBe(source`
key:
#comment
!tag
- one
- two
`)
})
test('explicit tag and comment on block sequence', () => {
const src = source`
key: !tag
#comment
- one
- two
`
const doc = YAML.parseDocument(src)
expect(String(doc)).toBe(source`
key:
#comment
!tag
- one
- two
`)
})
test('anchor on block sequence', () => {
const src = source`
key: &anchor
- one
- two
`
const doc = YAML.parseDocument(src)
expect(String(doc)).toBe(src)
})
test('anchor and explicit tag on block sequence', () => {
const src = source`
key: &anchor !tag
- one
- two
`
const doc = YAML.parseDocument(src)
expect(String(doc)).toBe(src)
})
test('explicit tag on empty mapping', () => {
const doc = new YAML.Document({ key: {} })
doc.get('key').tag = '!tag'
expect(String(doc)).toBe(source`
key: !tag {}
`)
})
test('explicit tag on single-line flow mapping', () => {
const src = source`
key: !tag { one: 1, two: 2 }
`
const doc = YAML.parseDocument(src)
expect(String(doc)).toBe(src)
})
test('explicit tag on multi-line flow mapping', () => {
const src = source`
key: !tag {
one: aaaaaaaaaa,
two: bbbbbbbbbb,
three: cccccccccc,
four: dddddddddd,
five: eeeeeeeeee
}
`
const doc = YAML.parseDocument(src)
expect(String(doc)).toBe(source`
key:
!tag {
one: aaaaaaaaaa,
two: bbbbbbbbbb,
three: cccccccccc,
four: dddddddddd,
five: eeeeeeeeee
}
`)
})
test('explicit tag on explicit-value block sequence', () => {
const src = source`
? [ key ]
: !tag
- one
- two
`
const doc = YAML.parseDocument(src)
expect(String(doc)).toBe(src)
})
})
})

test('eemeli/yaml#43: Quoting colons', () => {
Expand Down Expand Up @@ -702,7 +832,7 @@ describe('indentSeq: false', () => {
b: 2
map:
seq:
#sc
#sc
- a
`)
})
Expand All @@ -714,7 +844,7 @@ describe('indentSeq: false', () => {
b: 2
map:
seq:
#sc
#sc
- a
`)
})
Expand Down Expand Up @@ -1182,15 +1312,15 @@ describe('YAML.stringify on ast Document', () => {
})

describe('flow collection padding', () => {
const doc = new YAML.Document();
doc.contents = new YAML.YAMLSeq();
doc.contents.items = [1, 2];
doc.contents.flow = true;
const doc = new YAML.Document()
doc.contents = new YAML.YAMLSeq()
doc.contents.items = [1, 2]
doc.contents.flow = true

test('default', () => {
expect(doc.toString()).toBe('[ 1, 2 ]\n')
});
})
test('default', () => {
expect(doc.toString({flowCollectionPadding: false})).toBe('[1, 2]\n')
});
})
expect(doc.toString({ flowCollectionPadding: false })).toBe('[1, 2]\n')
})
})
7 changes: 6 additions & 1 deletion tests/doc/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,12 @@ date (00:00:00Z): 2002-12-14\n`)
test('eemeli/yaml#78', () => {
const set = new Set(['a', 'b', 'c'])
const str = YAML.stringify({ set }, { version: '1.1' })
expect(str).toBe(`set:\n !!set\n ? a\n ? b\n ? c\n`)
expect(str).toBe(source`
set: !!set
? a
? b
? c
`)
})
})

Expand Down