import Skypager from '.'

describe('Markdown Document Handling', function() {
  before(function() {
    if (!this.project) {
      this.project = Skypager.load(process.cwd(), {
        sync: false
      })
    }

    if (!this.doc) {
      this.doc = this.project.document('EXAMPLE.spec')
    }
  })  

  it('provides a way of querying the documents ast', function() {
    const textValues = this.doc.selectNodes('heading').map(node => node.textContent())
    textValues.should.include('Actual Input', 'Example', 'Setup', 'Teardown')
  })

  it('can detect frontmatter', function() {
    this.doc.hasFrontmatter().should.equal(true)
  })

  it('reads frontmatter', function() {
    this.doc.frontmatter.should.be.an('object')
      .that.is.not.empty
  })

  it('can tell the document title', function() {
    this.doc.documentTitle().should.equal('Example')
  })

  it('can compile the documents codeblocks using babel', function() {
    const codeBlocks = this.doc.compileCodeBlocks().values().flatten().value()

    codeBlocks.forEach(block => {
      block.should.have.property('compiled').that.is.not.empty
    })
  })

  it('exports useful attributes', function() {
    this.doc.exportables.should.be.an('object')    
    this.doc.exportables.should.have.property('html').that.is.a('string').that.is.not.empty
    this.doc.exportables.should.have.property('id', 'EXAMPLE.spec')
    this.doc.exportables.should.have.property('ast').that.is.an('object')
      .that.has.a.property('children')
        .that.is.an('array')
        .that.is.not.empty
  })

  describe('Document Node Utilities', function() {
    it('knows the heading path of any given heading', function() {
      this.doc.selectNodes('heading').forEach(heading => {
        heading.getHeadingPath().should.not.be.empty
      })

      const test = this.doc.selectOneNode('heading[depth=3]')
      test.getHeadingPath().should.equal('actual-input/code-sample-one')
    })


    it('can query nodes under a given section', function(done) {
      const test = this.doc.selectOneNode('heading[depth=2]')

      test.selectChildren('code')
        .then((codeBlocks) => {
          codeBlocks.should.not.be.empty
          codeBlocks.filter(c => c.type === 'code').length.should.equal(codeBlocks.length)
          done()
        })
        .catch((error) => done(error))
    })    
    
    it('can find all of the nodes under a given section', function(done) {
      const test = this.doc.selectOneNode('heading[depth=2]')

      test.headingRange()
        .then(({nodes}) => {
          nodes.should.not.be.empty
          done()
        })
        .catch((error) => done(error))
    })

    it('can find nodes under a heading synchronously', function() {
      const test = this.doc
      const nodes = test.headingsMap.actualInput.headingRangeSync() 

      nodes.should.not.be.empty
    })

    it('can select nodes under a heading synchronously', function() {
      const test = this.doc
      const codeBlocks = test.headingsMap.actualInput.selectHeadingChildrenSync('code')
      const blocks = test.headingsMap.actualInput.selectHeadingChildrenSync('blockquote')
      codeBlocks.should.not.be.empty
      blocks.should.be.empty
    })
  })
})