import { Eltro as t, assert} from 'eltro'
import { isObject, defaults } from '../core/defaults.mjs'

t.describe('#isObject()', () => {
  t.test('should return false for invalid objects', function() {
    let tests = [
      [],
      '',
      'asdf',
      12341,
      0,
    ]

    tests.forEach(function(check) {
      assert.strictEqual(isObject(check), false)
    })
  })
  t.test('should return true for valid objects', function() {
    let tests = [
      {},
      new Object(),
    ]

    tests.forEach(function(check) {
      assert.strictEqual(isObject(check), true)
    })
  })
})

t.describe('#defaults()', () => {
  t.test('should throw if original is missing or invalid', () => {
    assert.throws(function() { defaults() })
    assert.throws(function() { defaults('asdf') })
    assert.throws(function() { defaults('') })
    assert.throws(function() { defaults(null) })
    assert.throws(function() { defaults(1234) })
    assert.throws(function() { defaults([]) })
  })
  t.test('should not override existing variables', () => {
    let assertOutput = { a: 2 }
    defaults(assertOutput, { a: 1 })

    assert.deepStrictEqual(assertOutput, { a: 2 })
  })

  t.test('should allow nesting through objects', () => {
    let def = { a: { b: 2 } }
    let inside = { a: { c: 3} }
    defaults(inside, def)

    assert.deepStrictEqual(inside.a, {
      b: 2,
      c: 3,
    })
  })

  t.test('should not return new reference', () => {
    let assertInput = { a: 1 }
    let existing = assertInput
    defaults(assertInput, { b: 2 })

    assert.strictEqual(assertInput, existing)
  })
})
