text: import YAML from '../../src/index'
  
  describe('parse comments', () => {
    describe('body', () => {
      test('directives', () => {
        const src = '#comment\n%YAML 1.2 #comment\n---\nstring\n'
        const doc = YAML.parseDocument(src)
        expect(doc.commentBefore).toBe('comment\ncomment')
        expect(String(doc)).toBe('#comment\n#comment\n\n%YAML 1.2\n---\nstring\n')
      })
  
      test('body start comments', () => {
        const src = '---\n#comment\n#comment\nstring\n'
        const doc = YAML.parseDocument(src)
        expect(doc.contents.commentBefore).toBe('comment\ncomment')
        expect(String(doc)).toBe('#comment\n#comment\nstring\n')
      })
  
      test('body start comments with empty comment line', () => {
        const src = '---\n#comment\n#\n#comment\nstring\n'
        const doc = YAML.parseDocument(src)
        expect(doc.contents.commentBefore).toBe('comment\n\ncomment')
        expect(String(doc)).toBe('#comment\n#\n#comment\nstring\n')
      })
  
      test('body end comments', () => {
        const src = '\nstring\n#comment\n#comment\n'
        const doc = YAML.parseDocument(src)
        expect(doc.comment).toBe('comment\ncomment')
        expect(String(doc)).toBe('string\n\n#comment\n#comment\n')
      })
    })
  
    describe('top-level scalar comments', () => {
      test('plain', () => {
        const src = '#c0\nvalue #c1\n#c2'
        const doc = YAML.parseDocument(src)
        expect(doc.contents.commentBefore).toBe('c0')
        expect(doc.contents.comment).toBe('c1')
        expect(doc.comment).toBe('c2')
        expect(doc.contents.value).toBe('value')
        expect(doc.contents.range).toMatchObject([4, 13])
      })
  
      test('"quoted"', () => {
        const src = '#c0\n"value" #c1\n#c2'
        const doc = YAML.parseDocument(src)
        expect(doc.contents.commentBefore).toBe('c0')
        expect(doc.contents.comment).toBe('c1')
        expect(doc.comment).toBe('c2')
        expect(doc.contents.value).toBe('value')
        expect(doc.contents.range).toMatchObject([4, 15])
      })
  
      test('block', () => {
        const src = '#c0\n>- #c1\n value\n#c2\n'
        const doc = YAML.parseDocument(src)
        expect(doc.contents.commentBefore).toBe('c0')
        expect(doc.contents.comment).toBe('c1')
        expect(doc.comment).toBe('c2')
        expect(doc.contents.value).toBe('value')
        expect(doc.contents.range).toMatchObject([4, 18])
      })
    })
  
    describe('seq entry comments', () => {
      test('plain', () => {
        const src = `#c0
  - value 1
  #c1
  
  - value 2
  
  #c2`
        const doc = YAML.parseDocument(src)
        expect(doc).toMatchObject({
          contents: {
            items: [
              { commentBefore: 'c0', range: [6, 13] },
              { commentBefore: 'c1' }
            ],
            range: [4, 29]
          },
          comment: 'c2'
        })
      })
  
      test('multiline', () => {
        const src = `
  - value 1
  #c0
  #c1
  
  #c2
  - value 2
  
  #c3
  #c4`
        const doc = YAML.parseDocument(src)
        expect(doc).toMatchObject({
          contents: {
            items: [{}, { commentBefore: 'c0\nc1\nc2' }]
          },
          comment: 'c3\nc4'
        })
      })
    })
  
    describe('map entry comments', () => {
      test('plain', () => {
        const src = `#c0
  key1: value 1
  #c1
  
  key2: value 2
  
  #c2`
        const doc = YAML.parseDocument(src)
        expect(doc).toMatchObject({
          contents: {
            items: [{ commentBefore: 'c0' }, { commentBefore: 'c1' }]
          },
          comment: 'c2'
        })
      })
  
      test('multiline', () => {
        const src = `key1: value 1
  #c0
  #c1
  
  #c2
  key2: value 2
  
  #c3
  #c4`
        const doc = YAML.parseDocument(src)
        expect(doc).toMatchObject({
          contents: {
            items: [{}, { commentBefore: 'c0\nc1\nc2' }]
          },
          comment: 'c3\nc4'
        })
      })
    })
  
    describe('map-in-seq comments', () => {
      test('plain', () => {
        const src = `#c0
  - #c1
    k1: v1
    #c2
    k2: v2 #c3
  #c4
    k3: v3
  #c5\n`
        const doc = YAML.parseDocument(src)
        expect(doc.contents.items).toMatchObject([
          {
            commentBefore: 'c0\nc1',
            items: [
              {},
              { commentBefore: 'c2', value: { comment: 'c3' } },
              { commentBefore: 'c4' }
            ]
          }
        ])
        expect(doc.comment).toBe('c5')
        expect(String(doc)).toBe(`#c0
  #c1
  - k1: v1
    #c2
    k2: v2 #c3
    #c4
    k3: v3
  
  #c5\n`)
      })
    })
  
    describe('seq-in-map comments', () => {
      test('plain', () => {
        const src = `#c0
  k1: #c1
    - v1
  #c2
    - v2
    #c3
  k2:
    - v3 #c4
  #c5\n`
        const doc = YAML.parseDocument(src)
        expect(doc.contents.items).toMatchObject([
          {
            comment: 'c1',
            key: { commentBefore: 'c0', value: 'k1' },
            value: {
              items: [{ value: 'v1' }, { commentBefore: 'c2', value: 'v2' }],
              comment: 'c3'
            }
          },
          {
            key: { value: 'k2' },
            value: { items: [{ value: 'v3', comment: 'c4' }] }
          }
        ])
        expect(doc.comment).toBe('c5')
        expect(String(doc)).toBe(`#c0
  k1: #c1
    - v1
    #c2
    - v2
    #c3
  k2:
    - v3 #c4
  
  #c5\n`)
      })
    })
  })
  
  describe('stringify comments', () => {
    describe('single-line comments', () => {
      test('plain', () => {
        const src = 'string'
        const doc = YAML.parseDocument(src)
        doc.contents.comment = 'comment'
        expect(String(doc)).toBe('string #comment\n')
      })
  
      test('"quoted"', () => {
        const src = '"string\\u0000"'
        const doc = YAML.parseDocument(src)
        doc.contents.comment = 'comment'
        expect(String(doc)).toBe('"string\\0" #comment\n')
      })
  
      test('block', () => {
        const src = '>\nstring\n'
        const doc = YAML.parseDocument(src)
        doc.contents.comment = 'comment'
        expect(String(doc)).toBe('> #comment\nstring\n')
      })
    })
  
    describe('multi-line comments', () => {
      test('plain', () => {
        const src = 'string'
        const doc = YAML.parseDocument(src)
        doc.contents.comment = 'comment\nlines'
        expect(String(doc)).toBe('#comment\n#lines\nstring\n')
      })
  
      test('"quoted"', () => {
        const src = '"string\\u0000"'
        const doc = YAML.parseDocument(src)
        doc.contents.comment = 'comment\nlines'
        expect(String(doc)).toBe('"string\\0"\n#comment\n#lines\n')
      })
  
      test('block', () => {
        const src = '>\nstring\n'
        const doc = YAML.parseDocument(src)
        doc.contents.comment = 'comment\nlines'
        expect(String(doc)).toBe('> #comment lines\nstring\n')
      })
    })
  
    describe('document comments', () => {
      test('directive', () => {
        const src = '#c0\n---\nstring'
        const doc = YAML.parseDocument(src)
        expect(doc.commentBefore).toBe('c0')
        doc.commentBefore += '\nc1'
        expect(String(doc)).toBe('#c0\n#c1\n\nstring\n')
      })
    })
  
    describe('seq comments', () => {
      test('plain', () => {
        const src = '- value 1\n- value 2\n'
        const doc = YAML.parseDocument(src)
        doc.contents.commentBefore = 'c0'
        doc.contents.items[0].commentBefore = 'c1'
        doc.contents.items[1].commentBefore = 'c2'
        doc.contents.comment = 'c3'
        expect(String(doc)).toBe(
          `#c0
  #c1
  - value 1
  #c2
  - value 2
  #c3
  `
        )
      })
  
      test('multiline', () => {
        const src = '- value 1\n- value 2\n'
        const doc = YAML.parseDocument(src)
        doc.contents.items[0].commentBefore = 'c0\nc1'
        doc.contents.items[1].commentBefore = '\nc2\n\nc3'
        doc.contents.comment = 'c4\nc5'
        expect(String(doc)).toBe(
          `#c0
  #c1
  - value 1
  #
  #c2
  #
  #c3
  - value 2
  #c4
  #c5
  `
        )
      })
  
      test('seq-in-map', () => {
        const src = 'map:\n  - value 1\n  - value 2\n'
        const doc = YAML.parseDocument(src)
        doc.contents.items[0].key.commentBefore = 'c0'
        doc.contents.items[0].key.comment = 'c1'
        doc.contents.items[0].comment = 'c2'
        const seq = doc.contents.items[0].value
        seq.items[0].commentBefore = 'c3'
        seq.items[1].commentBefore = 'c4'
        seq.comment = 'c5'
        expect(String(doc)).toBe(
          `#c0
  ? map #c1
  : #c2
    #c3
    - value 1
    #c4
    - value 2
    #c5\n`
        )
      })
    })
  
    describe('map entry comments', () => {
      test('plain', () => {
        const src = 'key1: value 1\nkey2: value 2\n'
        const doc = YAML.parseDocument(src)
        doc.contents.items[0].commentBefore = 'c0'
        doc.contents.items[1].commentBefore = 'c1'
        doc.contents.items[1].comment = 'c2'
        doc.contents.items[1].value.spaceBefore = true
        doc.contents.comment = 'c3'
        expect(String(doc)).toBe(`#c0
  key1: value 1
  #c1
  key2: #c2
  
    value 2
  #c3\n`)
      })
  
      test('multiline', () => {
        const src = 'key1: value 1\nkey2: value 2\n'
        const doc = YAML.parseDocument(src)
        doc.contents.items[0].commentBefore = 'c0\nc1'
        doc.contents.items[1].commentBefore = '\nc2\n\nc3'
        doc.contents.items[1].comment = 'c4\nc5'
        doc.contents.items[1].value.spaceBefore = true
        doc.contents.items[1].value.commentBefore = 'c6'
        doc.contents.comment = 'c7\nc8'
        expect(String(doc)).toBe(
          `#c0
  #c1
  key1: value 1
  #
  #c2
  #
  #c3
  key2:
    #c4
    #c5
  
    #c6
    value 2
  #c7
  #c8
  `
        )
      })
    })
  })
  
  describe('blank lines', () => {
    describe('drop leading blank lines', () => {
      test('content', () => {
        const src = '\n\nstr\n'
        const doc = YAML.parseDocument(src)
        expect(String(doc)).toBe('str\n')
      })
  
      test('content comment', () => {
        const src = '\n\n#cc\n\nstr\n'
        const doc = YAML.parseDocument(src)
        expect(String(doc)).toBe('#cc\n\nstr\n')
      })
  
      test('directive', () => {
        const src = '\n\n%YAML 1.2\n---\nstr\n'
        const doc = YAML.parseDocument(src)
        expect(String(doc)).toBe('%YAML 1.2\n---\nstr\n')
      })
  
      test('directive comment', () => {
        const src = '\n\n#cc\n%YAML 1.2\n---\nstr\n'
        const doc = YAML.parseDocument(src)
        expect(String(doc)).toBe('#cc\n\n%YAML 1.2\n---\nstr\n')
      })
    })
  
    describe('drop trailing blank lines', () => {
      test('empty contents', () => {
        const src = '\n\n\n'
        const doc = YAML.parseDocument(src)
        expect(String(doc)).toBe('null\n')
      })
  
      test('scalar contents', () => {
        const src = 'str\n\n\n'
        const doc = YAML.parseDocument(src)
        expect(String(doc)).toBe('str\n')
      })
  
      test('seq contents', () => {
        const src = '- a\n- b\n\n\n'
        const doc = YAML.parseDocument(src)
        expect(String(doc)).toBe('- a\n- b\n')
      })
  
      test('empty/comment contents', () => {
        const src = '#cc\n\n\n'
        const doc = YAML.parseDocument(src)
        expect(String(doc)).toBe('#cc\n\nnull\n')
      })
    })
  
    test('between directive comment & directive', () => {
      const src = '#cc\n\n\n%YAML 1.2\n---\nstr\n'
      const doc = YAML.parseDocument(src)
      expect(String(doc)).toBe('#cc\n\n%YAML 1.2\n---\nstr\n')
    })
  
    test('after leading comment', () => {
      const src = '#cc\n\n\nstr\n'
      const doc = YAML.parseDocument(src)
      expect(String(doc)).toBe('#cc\n\nstr\n')
    })
  
    test('between seq items', () => {
      const src = '- a\n\n- b\n\n\n- c\n'
      const doc = YAML.parseDocument(src)
      expect(String(doc)).toBe('- a\n\n- b\n\n- c\n')
    })
  
    test('between seq items with leading comments', () => {
      const src = '#A\n- a\n\n#B\n- b\n\n\n#C\n\n- c\n'
      const doc = YAML.parseDocument(src)
      expect(String(doc)).toBe('#A\n- a\n\n#B\n- b\n\n#C\n- c\n')
    })
  
    describe('not after block scalar with keep chomping', () => {
      const cases = [
        { name: 'in seq', src: '- |+\n  a\n\n- b\n' },
        { name: 'in map', src: 'a: |+\n  A\n\nb: B\n' },
        { name: 'in seq in map', src: 'a:\n  - |+\n    A\n\nb: B\n' }
      ]
      for (const { name, src } of cases) {
        test(name, () => {
          const doc = YAML.parseDocument(src)
          expect(String(doc)).toBe(src)
          expect(doc.contents.items[1]).not.toHaveProperty('spaceBefore', true)
          doc.contents.items[1].spaceBefore = true
          expect(String(doc)).toBe(src)
        })
      }
  
      test('as contents', () => {
        const src = '|+\n a\n\n#c\n'
        const doc = YAML.parseDocument(src)
        expect(doc).toMatchObject({
          comment: 'c',
          contents: { value: 'a\n\n' }
        })
        expect(String(doc)).toBe(src)
      })
    })
  
    test('before block map values', () => {
      const src = 'a:\n\n  1\nb:\n\n  #c\n  2\n'
      const doc = YAML.parseDocument(src)
      expect(doc.contents).toMatchObject({
        items: [
          {
            key: { value: 'a' },
            value: { value: 1, spaceBefore: true }
          },
          {
            key: { value: 'b' },
            value: { value: 2, commentBefore: 'c', spaceBefore: true }
          }
        ]
      })
      expect(String(doc)).toBe(src)
    })
  
    describe('after block value', () => {
      test('in seq', () => {
        const src = '- |\n a\n\n- >-\n b\n\n- |+\n c\n\n- d\n'
        const doc = YAML.parseDocument(src)
        expect(String(doc)).toBe('- |\n  a\n\n- >-\n  b\n\n- |+\n  c\n\n- d\n')
      })
  
      test('in map', () => {
        const src = 'A: |\n a\n\nB: >-\n b\n\nC: |+\n c\n\nD: d\n'
        const doc = YAML.parseDocument(src)
        expect(String(doc)).toBe(
          'A: |\n  a\n\nB: >-\n  b\n\nC: |+\n  c\n\nD: d\n'
        )
      })
    })
  
    describe('flow collections', () => {
      test('flow seq', () => {
        const src = '[1,\n\n2,\n3,\n\n4\n\n]'
        const doc = YAML.parseDocument(src)
        expect(doc.contents).toMatchObject({
          items: [
            { value: 1 },
            { value: 2, spaceBefore: true },
            { value: 3 },
            { value: 4, spaceBefore: true }
          ]
        })
        expect(String(doc)).toBe('[\n  1,\n\n  2,\n  3,\n\n  4\n]\n')
      })
  
      test('flow map', () => {
        const src = '{\n\na: 1,\n\nb: 2 }'
        const doc = YAML.parseDocument(src)
        expect(doc.contents).toMatchObject({
          items: [
            { key: { value: 'a' }, value: { value: 1 }, spaceBefore: true },
            { key: { value: 'b' }, value: { value: 2 }, spaceBefore: true }
          ]
        })
      })
  
      test('flow map value comments & spaces', () => {
        const src = '{\n  a:\n    #c\n    1,\n  b:\n\n    #d\n    2\n}\n'
        const doc = YAML.parseDocument(src)
        expect(doc.contents).toMatchObject({
          items: [
            {
              key: { value: 'a' },
              value: { value: 1, commentBefore: 'c' }
            },
            {
              key: { value: 'b' },
              value: { value: 2, commentBefore: 'd', spaceBefore: true }
            }
          ]
        })
        expect(String(doc)).toBe(src)
      })
    })
  })
  
  describe('eemeli/yaml#18', () => {
    test('reported', () => {
      const src = `test1:
    foo: #123
      bar: 1\n`
      const doc = YAML.parseDocument(src)
      expect(String(doc)).toBe(src)
    })
  
    test('minimal', () => {
      const src = `foo: #123\n  bar: baz\n`
      const doc = YAML.parseDocument(src)
      expect(String(doc)).toBe(src)
    })
  })
  
  describe('eemeli/yaml#28', () => {
    test('reported', () => {
      const src = `# This comment is ok
  entryA:
    - foo
  
  entryB:
    - bar # bar comment
  
  # Ending comment
  # Ending comment 2\n`
      const doc = YAML.parseDocument(src)
      expect(String(doc)).toBe(`# This comment is ok
  entryA:
    - foo
  
  entryB:
    - bar # bar comment
  
  # Ending comment
  # Ending comment 2\n`)
    })
  
    test('collection end comment', () => {
      const src = `a: b #c\n#d\n`
      const doc = YAML.parseDocument(src)
      expect(String(doc)).toBe(`a: b #c\n\n#d\n`)
    })
  
    test('comment association by indentation', () => {
      const src = `
  a:
    - b #c
  #d\n`
      const cst = YAML.parseCST(src)
      const collection = cst[0].contents[1]
      expect(collection.items).toHaveLength(2)
      const comment = cst[0].contents[2]
      expect(comment.type).toBe('COMMENT')
      expect(comment.comment).toBe('d')
    })
  
    test('blank line after seq in map', () => {
      const src = `a:
    - aa
  
  b:
    - bb
  
  c: cc\n`
      const doc = YAML.parseDocument(src)
      expect(String(doc)).toBe(src)
    })
  
    test('blank line after map in seq', () => {
      const src = `- a: aa
  
  - b: bb
    c: cc
  
  - d: dd\n`
      const doc = YAML.parseDocument(src)
      expect(String(doc)).toBe(src)
    })
  })
  
  describe('collection end comments', () => {
    test('seq in seq', () => {
      const src = `#0
  - - a
    - b
    #1
  
  #2
  - d\n`
      const doc = YAML.parseDocument(src)
      expect(doc.contents).toMatchObject({
        items: [
          { items: [{ value: 'a' }, { value: 'b' }], comment: '1' },
          { spaceBefore: true, commentBefore: '2', value: 'd' }
        ]
      })
      expect(String(doc)).toBe(src)
    })
  
    test('map in seq', () => {
      const src = `#0
  - a: 1
    b: 2
    #1
  
  #2
  - d\n`
      const doc = YAML.parseDocument(src)
      expect(doc.contents).toMatchObject({
        items: [
          {
            items: [
              { key: { value: 'a' }, value: { value: 1 } },
              { key: { value: 'b' }, value: { value: 2 } }
            ],
            comment: '1'
          },
          { spaceBefore: true, commentBefore: '2', value: 'd' }
        ]
      })
      expect(String(doc)).toBe(src)
    })
  
    test('seq in map', () => {
      const src = `#0
  a:
    - b
    - c
    #1
  
  #2
  d: 1\n`
      const doc = YAML.parseDocument(src)
      expect(doc.contents).toMatchObject({
        items: [
          {
            key: { value: 'a' },
            value: { items: [{ value: 'b' }, { value: 'c' }], comment: '1' }
          },
          {
            spaceBefore: true,
            commentBefore: '2',
            key: { value: 'd' },
            value: { value: 1 }
          }
        ]
      })
      expect(String(doc)).toBe(src)
    })
  
    test('map in map', () => {
      const src = `#0
  a:
    b: 1
    c: 2
    #1
  
  #2
  d: 1\n`
      const doc = YAML.parseDocument(src)
      expect(doc.contents).toMatchObject({
        items: [
          {
            key: { value: 'a' },
            value: {
              items: [
                { key: { value: 'b' }, value: { value: 1 } },
                { key: { value: 'c' }, value: { value: 2 } }
              ],
              comment: '1'
            }
          },
          {
            spaceBefore: true,
            commentBefore: '2',
            key: { value: 'd' },
            value: { value: 1 }
          }
        ]
      })
      expect(String(doc)).toBe(src)
    })
  
    test('indented seq in map in seq', () => {
      const src = `#0
  a:
    #1
    - b:
        - c
  
    #2
    - e\n`
      const doc = YAML.parseDocument(src)
      expect(doc.contents).toMatchObject({
        items: [
          {
            key: { value: 'a' },
            value: {
              commentBefore: '1',
              items: [
                {
                  items: [
                    {
                      key: { value: 'b' },
                      value: { items: [{ value: 'c' }] }
                    }
                  ]
                },
                { spaceBefore: true, commentBefore: '2', value: 'e' }
              ]
            }
          }
        ]
      })
      expect(String(doc)).toBe(src)
    })
  })
  