/* eslint-env mocha */
import staticTree from './staticTree'
import { Sequence, Parallel } from './primitives'
import assert from 'assert'

describe('StaticTree', () => {
  it('should create a static tree of an array', () => {
    const tree = staticTree('Some name', [
      function test() {},
      { shortHand() {} }.shortHand,
    ])

    assert.equal(tree.items.length, 2)
    assert.equal(tree._functionTreePrimitive, true)
    assert.equal(tree.type, 'sequence')
    assert.equal(tree.items[0].name, 'test')
    assert.equal(tree.items[1].name, 'shortHand')
    assert.equal(tree.items[0].functionIndex, 0)
    assert.ok(tree.items[0].function)
  })
  it('should create a static tree of a function', () => {
    const tree = staticTree('Some name', function test() {})

    assert.equal(tree._functionTreePrimitive, true)
    assert.equal(tree.type, 'sequence')
    assert.equal(tree.items.length, 1)
    assert.equal(tree.items[0].name, 'test')
    assert.equal(tree.items[0].functionIndex, 0)
    assert.ok(tree.items[0].function)
  })
  it('should throw when unexpected entry in tree', () => {
    assert.throws(
      () => {
        staticTree('Some name', [function a() {}, 1])
      },
      err => {
        if (
          err instanceof Error &&
          err.name === 'FunctionTreeError' &&
          err.toJSON
        ) {
          return (
            err.toJSON().message.indexOf(`[
  a
  number <-- PROBLEM
]`) === 34
          )
        }
      }
    )
    assert.throws(
      () => {
        staticTree('someName', 1)
      },
      err => {
        if (
          err instanceof Error &&
          err.name === 'FunctionTreeError' &&
          err.toJSON
        ) {
          return err.toJSON().message === 'Unexpected entry in tree'
        }
      }
    )
  })
  it('should handle paths', () => {
    const tree = staticTree('Some name', [
      function a() {},
      {
        foo: [function b() {}],
      },
    ])

    assert.equal(tree._functionTreePrimitive, true)
    assert.equal(tree.type, 'sequence')
    assert.equal(tree.items.length, 1)
    assert.equal(tree.items[0].name, 'a')
    assert.equal(tree.items[0].functionIndex, 0)
    assert.ok(tree.items[0].function)
    assert.equal(tree.items[0].outputs.foo.items[0].name, 'b')
    assert.equal(tree.items[0].outputs.foo.items[0].functionIndex, 1)
    assert.ok(tree.items[0].outputs.foo.items[0].function)
  })
  it('should identify parallel execution', () => {
    const tree = staticTree('Some name', [
      new Parallel([function a() {}, function b() {}]),
    ])

    assert.equal(tree._functionTreePrimitive, true)
    assert.equal(tree.type, 'sequence')
    assert.equal(tree.items.length, 1)
    assert.equal(tree.items[0].items[0].name, 'a')
    assert.equal(tree.items[0].items[0].functionIndex, 0)
    assert.ok(tree.items[0].items[0].function)
    assert.equal(tree.items[0].items[1].name, 'b')
    assert.equal(tree.items[0].items[1].functionIndex, 1)
    assert.ok(tree.items[0].items[1].function)
  })
  it('should identify parallel execution at root', () => {
    const tree = staticTree(
      'Some name',
      new Parallel([function a() {}, function b() {}])
    )

    assert.equal(tree._functionTreePrimitive, true)
    assert.equal(tree.type, 'parallel')
    assert.equal(tree.items.length, 2)
    assert.equal(tree.items[0].functionIndex, 0)
    assert.ok(tree.items[0].function)
    assert.equal(tree.items[1].name, 'b')
    assert.equal(tree.items[1].functionIndex, 1)
    assert.ok(tree.items[1].function)
  })
  it('should not identify parallel execution as outputs', () => {
    const tree = staticTree('Some name', [
      function someFunc() {},
      new Parallel([function a() {}, function b() {}]),
    ])

    assert.equal(tree._functionTreePrimitive, true)
    assert.equal(tree.type, 'sequence')
    assert.equal(tree.items.length, 2)
    assert.equal(tree.items[0].name, 'someFunc')
    assert.equal(tree.items[0].functionIndex, 0)

    assert.equal(tree.items[1]._functionTreePrimitive, true)
    assert.equal(tree.items[1].items[0].name, 'a')
    assert.equal(tree.items[1].items[0].functionIndex, 1)
    assert.equal(tree.items[1].items[1].name, 'b')
    assert.equal(tree.items[1].items[1].functionIndex, 2)
  })
  it('should allow sequence in parallel', () => {
    const tree = staticTree('Some name', [
      function someFunc() {},
      new Parallel([function a() {}, new Sequence([function b() {}])]),
    ])

    assert.equal(tree._functionTreePrimitive, true)
    assert.equal(tree.type, 'sequence')
    assert.equal(tree.items.length, 2)
    assert.equal(tree.items[0].name, 'someFunc')
    assert.equal(tree.items[0].functionIndex, 0)

    assert.equal(tree.items[1]._functionTreePrimitive, true)
    assert.equal(tree.items[1].items[0].name, 'a')
    assert.equal(tree.items[1].items[0].functionIndex, 1)
    assert.equal(tree.items[1].items[1].items[0].name, 'b')
    assert.equal(tree.items[1].items[1].items[0].functionIndex, 2)
  })
})

@@ -1391,31 +1391,97 @@
 age.
-indexOf(%60%5B%0A  a%0A
+replace(/%5Cn/g, '').trim() ===%0A            'Unexpected entry in %22Some name%22. %5B  a,
   number
  %3C--
@@ -1476,16 +1476,17 @@
   number
+,
  %3C-- PRO
@@ -1493,19 +1493,10 @@
 BLEM
-%0A%5D%60) === 34
+%5D'
 %0A   

fix throw test to handle linebreaks