text: const assert = require('assert')
  const { check, shallowCheck, optional } = require('../index')
  const {
      _equal,
      _isNull,
      _isUndefined,
      _isString,
      _isNumber,
      _isBoolean,
      _isObject,
      _isArray,
      _typeCheck,
      _isFunction,
      _isSymbol,
  } = require('../src/util')
  
  const models = [
      // using literal
      null,
      undefined,
      '',
      1,
      0b1111,
      // eslint-disable-next-line node/no-unsupported-features/es-builtins
      BigInt('0b11111'),
      NaN,
      true,
      false,
      Symbol(),
      {},
      [],
      function () {
      },
      () => {
      },
      // using constructor
      new String(),
      new Number(),
      new Boolean(),
      new Object(),
      new Array(),
      new Function(),
      new Date(),
      new Map(),
      new Set(),
  ]
  
  const types = [
      'Null',
      'Undefined',
      'String',
      'Number',
      'Number',
      'BigInt',
      'Number',
      'Boolean',
      'Boolean',
      'Symbol',
      'Object',
      'Array',
      'Function',
      'Function',
      'String',
      'Number',
      'Boolean',
      'Object',
      'Array',
      'Function',
      'Date',
      'Map',
      'Set',
  ]
  
  String.prototype.foo = 1
  Number.prototype.foo = 1
  Boolean.prototype.foo = 1
  Symbol.prototype.foo = 1
  Object.prototype.foo = 1
  Array.prototype.foo = 1
  Date.prototype.foo = 1
  Map.prototype.foo = 1
  Set.prototype.foo = 1
  Function.prototype.foo = 1
  
  function run (m, s) {
      const a = check(m, s)
      const b = check(m)(s)
      const c = shallowCheck(m, s)
      const d = shallowCheck(m)(s)
      return [a, b, c, d]
  }
  
  describe('Test all', () => {
      describe('Test utilities', () => {
          describe('_typeCheck', () => {
              for (let i = 0; i < models.length; i += 1) {
                  it(`check ${types[i]}`, () => {
                      assert.strictEqual(_typeCheck(models[i]), types[i])
                  })
              }
          })
  
          describe('_isNull', () => {
              for (let i = 0; i < models.length; i += 1) {
                  it(`check ${types[i]}`, () => {
                      const v = models[i]
                      if (types[i] === 'Null') {
                          assert.strictEqual(_isNull(v), true)
                      } else {
                          assert.strictEqual(_isNull(v), false)
                      }
                  })
              }
          })
  
          describe('_isUndefined', () => {
              for (let i = 0; i < models.length; i += 1) {
                  it(`check ${types[i]}`, () => {
                      const v = models[i]
                      if (types[i] === 'Undefined') {
                          assert.strictEqual(_isUndefined(v), true)
                      } else {
                          assert.strictEqual(_isUndefined(v), false)
                      }
                  })
              }
          })
  
          describe('_isString', () => {
              for (let i = 0; i < models.length; i += 1) {
                  it(`check ${types[i]}`, () => {
                      const v = models[i]
                      if (types[i] === 'String') {
                          assert.strictEqual(_isString(v), true)
                      } else {
                          assert.strictEqual(_isString(v), false)
                      }
                  })
              }
          })
  
          describe('_isSymbol', () => {
              for (let i = 0; i < models.length; i += 1) {
                  it(`check ${types[i]}`, () => {
                      const v = models[i]
                      if (types[i] === 'Symbol') {
                          assert.strictEqual(_isSymbol(v), true)
                      } else {
                          assert.strictEqual(_isSymbol(v), false)
                      }
                  })
              }
          })
  
          describe('_isNumber', () => {
              for (let i = 0; i < models.length; i += 1) {
                  it(`check ${types[i]}`, () => {
                      const v = models[i]
                      if (types[i] === 'Number') {
                          assert.strictEqual(_isNumber(v), true)
                      } else {
                          assert.strictEqual(_isNumber(v), false)
                      }
                  })
              }
          })
  
          describe('_isBoolean', () => {
              for (let i = 0; i < models.length; i += 1) {
                  it(`check ${types[i]}`, () => {
                      const v = models[i]
                      if (types[i] === 'Boolean') {
                          assert.strictEqual(_isBoolean(v), true)
                      } else {
                          assert.strictEqual(_isBoolean(v), false)
                      }
                  })
              }
          })
  
          describe('_isObject', () => {
              for (let i = 0; i < models.length; i += 1) {
                  it(`check ${types[i]}`, () => {
                      const v = models[i]
                      if (types[i] === 'Object') {
                          assert.strictEqual(_isObject(v), true)
                      } else {
                          assert.strictEqual(_isObject(v), false)
                      }
                  })
              }
          })
  
          describe('_isArray', () => {
              for (let i = 0; i < models.length; i += 1) {
                  it(`check ${types[i]}`, () => {
                      const v = models[i]
                      if (types[i] === 'Array') {
                          assert.strictEqual(_isArray(v), true)
                      } else {
                          assert.strictEqual(_isArray(v), false)
                      }
                  })
              }
          })
  
          describe('_isFunction', () => {
              for (let i = 0; i < models.length; i += 1) {
                  it(`check ${types[i]}`, () => {
                      const v = models[i]
                      if (types[i] === 'Function') {
                          assert.strictEqual(_isFunction(v), true)
                      } else {
                          assert.strictEqual(_isFunction(v), false)
                      }
                  })
              }
          })
  
          describe('_equal', () => {
              for (let i = 0; i < models.length; i += 1) {
                  it(`check ${types[i]}`, () => {
                      const v = models[i]
                      assert.strictEqual(_equal(v, v), true)
                  })
              }
          })
      })
  
      describe('Test library', () => {
          describe('Root optional', () => {
              const models = [
                  optional(1),
                  optional(NaN),
                  optional(''),
                  optional(true),
                  optional(Symbol()),
                  optional([]),
                  optional({}),
                  optional(new Object()),
                  optional(new Array()),
                  optional(new Set()),
                  optional(new Date()),
                  optional(new Map()),
                  optional(function () {}),
              ]
  
              for (const m of models) {
                  const [a, b, c, d] = run(m, undefined)
  
                  it(`check with ${_typeCheck(m)}`, () => {
                      assert.strictEqual(a, true)
                      assert.strictEqual(b, true)
                      assert.strictEqual(c, true)
                      assert.strictEqual(d, true)
                  })
              }
          })
  
          describe('Test any', () => {
              for (const m of models) {
                  const [a, b, c, d] = run('any', m)
  
                  it(`check with ${_typeCheck(m)}`, () => {
                      assert.strictEqual(a, true)
                      assert.strictEqual(b, true)
                      assert.strictEqual(c, true)
                      assert.strictEqual(d, true)
                  })
              }
          })
  
          describe('Test Primitives', () => {
              describe('Symbol', () => {
                  for (const m of models) {
                      const [a, b, c, d] = run(m, Symbol())
  
                      it(`with ${_typeCheck(m)}`, () => {
                          if (_isSymbol(m)) {
                              assert.strictEqual(a, true)
                              assert.strictEqual(b, true)
                              assert.strictEqual(c, true)
                              assert.strictEqual(d, true)
                          } else {
                              assert.strictEqual(a, false)
                              assert.strictEqual(b, false)
                              assert.strictEqual(c, false)
                              assert.strictEqual(d, false)
                          }
                      })
                  }
              })
  
              describe('Null', () => {
                  for (const m of models) {
                      const [a, b, c, d] = run(m, null)
  
                      it(`with ${_typeCheck(m)}`, () => {
                          if (_isNull(m)) {
                              assert.strictEqual(a, true)
                              assert.strictEqual(b, true)
                              assert.strictEqual(c, true)
                              assert.strictEqual(d, true)
                          } else {
                              assert.strictEqual(a, false)
                              assert.strictEqual(b, false)
                              assert.strictEqual(c, false)
                              assert.strictEqual(d, false)
                          }
                      })
                  }
              })
  
              describe('Undefined', () => {
                  for (const m of models) {
                      const [a, b, c, d] = run(m, undefined)
  
                      it(`with ${_typeCheck(m)}`, () => {
                          if (_isUndefined(m)) {
                              assert.strictEqual(a, true)
                              assert.strictEqual(b, true)
                              assert.strictEqual(c, true)
                              assert.strictEqual(d, true)
                          } else {
                              assert.strictEqual(a, false)
                              assert.strictEqual(b, false)
                              assert.strictEqual(c, false)
                              assert.strictEqual(d, false)
                          }
                      })
                  }
              })
  
              describe('String', () => {
                  for (const m of models) {
                      const [a, b, c, d] = run(m, '')
  
                      it(`with ${_typeCheck(m)}`, () => {
                          if (_isString(m)) {
                              assert.strictEqual(a, true)
                              assert.strictEqual(b, true)
                              assert.strictEqual(c, true)
                              assert.strictEqual(d, true)
                          } else {
                              assert.strictEqual(a, false)
                              assert.strictEqual(b, false)
                              assert.strictEqual(c, false)
                              assert.strictEqual(d, false)
                          }
                      })
                  }
              })
  
              describe('Number', () => {
                  for (const m of models) {
                      const [a, b, c, d] = run(m, 1)
  
                      it(`with ${_typeCheck(m)}`, () => {
                          if (_isNumber(m)) {
                              assert.strictEqual(a, true)
                              assert.strictEqual(b, true)
                              assert.strictEqual(c, true)
                              assert.strictEqual(d, true)
                          } else {
                              assert.strictEqual(a, false)
                              assert.strictEqual(b, false)
                              assert.strictEqual(c, false)
                              assert.strictEqual(d, false)
                          }
                      })
                  }
              })
  
              describe('Boolean', () => {
                  for (const m of models) {
                      const [a, b, c, d] = run(m, true)
  
                      it(`with ${_typeCheck(m)}`, () => {
                          if (_isBoolean(m)) {
                              assert.strictEqual(a, true)
                              assert.strictEqual(b, true)
                              assert.strictEqual(c, true)
                              assert.strictEqual(d, true)
                          } else {
                              assert.strictEqual(a, false)
                              assert.strictEqual(b, false)
                              assert.strictEqual(c, false)
                              assert.strictEqual(d, false)
                          }
                      })
                  }
              })
          })
  
          describe('Test Composite', () => {
              describe('Date', () => {
                  const data = new Date()
                  for (const m of models) {
                      const [a, b, c, d] = run(m, data)
  
                      it(`with ${_typeCheck(m)}`, () => {
                          if (_typeCheck(m).indexOf('Date') !== -1) {
                              assert.strictEqual(a, true)
                              assert.strictEqual(b, true)
                              assert.strictEqual(c, true)
                              assert.strictEqual(d, true)
                          } else {
                              assert.strictEqual(a, false)
                              assert.strictEqual(b, false)
                              assert.strictEqual(c, false)
                              assert.strictEqual(d, false)
                          }
                      })
                  }
              })
  
              describe('Function', () => {
                  const data = new Function()
                  for (const m of models) {
                      const [a, b, c, d] = run(m, data)
  
                      it(`with ${_typeCheck(m)}`, () => {
                          if (_isFunction(m)) {
                              assert.strictEqual(a, true)
                              assert.strictEqual(b, true)
                              assert.strictEqual(c, true)
                              assert.strictEqual(d, true)
                          } else {
                              assert.strictEqual(a, false)
                              assert.strictEqual(b, false)
                              assert.strictEqual(c, false)
                              assert.strictEqual(d, false)
                          }
                      })
                  }
              })
  
              describe('Map', () => {
                  const data = new Map()
                  for (const m of models) {
                      const [a, b, c, d] = run(m, data)
  
                      it(`with ${_typeCheck(m)}`, () => {
                          if (Object.prototype.toString.call(m).indexOf('Map') !== -1) {
                              assert.strictEqual(a, true)
                              assert.strictEqual(b, true)
                              assert.strictEqual(c, true)
                              assert.strictEqual(d, true)
                          } else {
                              assert.strictEqual(a, false)
                              assert.strictEqual(b, false)
                              assert.strictEqual(c, false)
                              assert.strictEqual(d, false)
                          }
                      })
                  }
              })
  
              describe('Set', () => {
                  const data = new Set()
                  for (const m of models) {
                      const [a, b, c, d] = run(m, data)
  
                      it(`with ${_typeCheck(m)}`, () => {
                          if (Object.prototype.toString.call(m).indexOf('Set') !== -1) {
                              assert.strictEqual(a, true)
                              assert.strictEqual(b, true)
                              assert.strictEqual(c, true)
                              assert.strictEqual(d, true)
                          } else {
                              assert.strictEqual(a, false)
                              assert.strictEqual(b, false)
                              assert.strictEqual(c, false)
                              assert.strictEqual(d, false)
                          }
                      })
                  }
              })
  
              describe('Object', () => {
                  const obj = {
                      a: '',
                      b: 1,
                      c: true,
                      d: null,
                      e: undefined,
                      f: {},
                      g: [],
                      h: 'any',
                  }
  
                  for (const m of models) {
                      const [a, b, c, d] = run(m, {})
  
                      it(`with ${_typeCheck(m)}`, () => {
                          if (_isObject(m)) {
                              assert.strictEqual(a, true)
                              assert.strictEqual(b, true)
                              assert.strictEqual(c, true)
                              assert.strictEqual(d, true)
                          } else {
                              assert.strictEqual(a, false)
                              assert.strictEqual(b, false)
                              assert.strictEqual(c, false)
                              assert.strictEqual(d, false)
                          }
                      })
                  }
  
                  it(`equal`, () => {
                      const [a, b, c, d] = run(obj, obj)
                      assert.strictEqual(a, true)
                      assert.strictEqual(b, true)
                      assert.strictEqual(c, true)
                      assert.strictEqual(d, true)
                  })
  
                  it(`empty model vs object`, () => {
                      const [a, b, c, d] = run({}, { a: 1 })
                      assert.strictEqual(a, true)
                      assert.strictEqual(b, true)
                      assert.strictEqual(c, true)
                      assert.strictEqual(d, true)
                  })
  
                  it(`model vs empty object`, () => {
                      const [a, b, c, d] = run({ a: 1 }, {})
                      assert.strictEqual(a, false)
                      assert.strictEqual(b, false)
                      assert.strictEqual(c, false)
                      assert.strictEqual(d, false)
                  })
  
                  it(`plain model - incompatible`, () => {
                      const [a, b, c, d] = run({ a: '' }, { a: 1 })
                      assert.strictEqual(a, false)
                      assert.strictEqual(b, false)
                      assert.strictEqual(c, false)
                      assert.strictEqual(d, false)
                  })
  
                  it(`nested model`, () => {
                      const [a, b, c, d] = run({ a: { b: 1 } }, { a: { b: 1 } })
                      assert.strictEqual(a, true)
                      assert.strictEqual(b, true)
                      assert.strictEqual(c, true)
                      assert.strictEqual(d, true)
                  })
  
                  it(`nested model - incompatible`, () => {
                      const [a, b, c, d] = run({ a: { b: 1 } }, { a: { b: '1' } })
                      assert.strictEqual(a, false)
                      assert.strictEqual(b, false)
                      assert.strictEqual(c, true)
                      assert.strictEqual(d, true)
                  })
  
                  // optional
                  it(`plain model with optional`, () => {
                      const [a, b, c, d] = run({
                          a: 1,
                          b: optional('1'),
                      }, {
                          a: 1,
                      })
                      assert.strictEqual(a, true)
                      assert.strictEqual(b, true)
                      assert.strictEqual(c, true)
                      assert.strictEqual(d, true)
                  })
  
                  it(`plain model with all optional`, () => {
                      const [a, b, c, d] = run({
                          a: optional(true),
                          b: optional(Symbol()),
                      }, {})
                      assert.strictEqual(a, true)
                      assert.strictEqual(b, true)
                      assert.strictEqual(c, true)
                      assert.strictEqual(d, true)
                  })
  
                  it(`plain model with optional - incompatible`, () => {
                      const [a, b, c, d] = run({
                          a: 1,
                          b: optional('1'),
                      }, {
                          a: 1,
                          b: 2,
                      })
                      assert.strictEqual(a, false)
                      assert.strictEqual(b, false)
                      assert.strictEqual(c, false)
                      assert.strictEqual(d, false)
                  })
  
                  // nested optional
                  it(`nested model with optional`, () => {
                      const [a, b, c, d] = run({
                          a: {
                              a: 1,
                              b: optional(1),
                          },
                      }, {
                          a: {
                              a: 1,
                          },
                      })
                      assert.strictEqual(a, true)
                      assert.strictEqual(b, true)
                      assert.strictEqual(c, true)
                      assert.strictEqual(d, true)
                  })
  
                  it(`nested model with all optional`, () => {
                      const [a, b, c, d] = run({
                          a: {
                              a: optional(1),
                              b: optional(1),
                          },
                      }, {
                          a: {},
                      })
                      assert.strictEqual(a, true)
                      assert.strictEqual(b, true)
                      assert.strictEqual(c, true)
                      assert.strictEqual(d, true)
                  })
  
                  it(`nested model with all optional - incompatible`, () => {
                      const [a, b, c, d] = run({
                          a: {
                              a: optional(1),
                              b: optional(1),
                          },
                      }, {
                          a: {
                              a: '',
                              b: true,
                          },
                      })
  
                      assert.strictEqual(a, false)
                      assert.strictEqual(b, false)
                      assert.strictEqual(c, true)
                      assert.strictEqual(d, true)
                  })
  
                  it(`nested model with optional - incompatible`, () => {
                      const [a, b, c, d] = run({
                          a: {
                              a: 1,
                              b: optional(1),
                          },
                      }, {
                          a: {
                              a: 1,
                              b: '1',
                          },
                      })
  
                      assert.strictEqual(a, false)
                      assert.strictEqual(b, false)
                      assert.strictEqual(c, true)
                      assert.strictEqual(d, true)
                  })
  
                  it(`optional null - error`, () => {
                      try {
                          check({
                              a: optional(null),
                          }, {})
                      } catch (e) {
                          assert.strictEqual(e, 'optional does not accept null or undefined')
                      }
                  })
  
                  it(`optional undefined - error`, () => {
                      try {
                          check({
                              a: optional(undefined),
                          }, {})
                      } catch (e) {
                          assert.strictEqual(e, 'optional does not accept null or undefined')
                      }
                  })
              })
  
              describe('Array', () => {
                  for (const m of models) {
                      const [a, b, c, d] = run(m, [])
  
                      it(`with ${_typeCheck(m)}`, () => {
                          if (_isArray(m)) {
                              assert.strictEqual(a, true)
                              assert.strictEqual(b, true)
                              assert.strictEqual(c, true)
                              assert.strictEqual(d, true)
                          } else {
                              assert.strictEqual(a, false)
                              assert.strictEqual(b, false)
                              assert.strictEqual(c, false)
                              assert.strictEqual(d, false)
                          }
                      })
                  }
  
                  describe('nested optional', () => {
                      const [a, b, c, d] = run([optional(1)], [undefined, undefined])
                      assert.strictEqual(a, true)
                      assert.strictEqual(b, true)
                      assert.strictEqual(c, true)
                      assert.strictEqual(d, true)
                  })
  
                  describe('nested optional - incompatible', () => {
                      const [a, b, c, d] = run([optional(1)], ['1', undefined])
                      assert.strictEqual(a, false)
                      assert.strictEqual(b, false)
                      assert.strictEqual(c, false)
                      assert.strictEqual(d, false)
                  })
  
                  describe('double nested optional', () => {
                      const [a, b, c, d] = run([[optional(1)]], [[undefined], [undefined]])
                      assert.strictEqual(a, true)
                      assert.strictEqual(b, true)
                      assert.strictEqual(c, true)
                      assert.strictEqual(d, true)
                  })
  
                  describe('double nested optional - incompatible', () => {
                      const [a, b, c, d] = run([[optional(1)]], [['1'], [undefined]])
                      assert.strictEqual(a, false)
                      assert.strictEqual(b, false)
                      assert.strictEqual(c, true)
                      assert.strictEqual(d, true)
                  })
  
                  describe('plain', () => {
                      it(`incompatible`, () => {
                          const [a, b, c, d] = run([1], [''])
                          assert.strictEqual(a, false)
                          assert.strictEqual(b, false)
                          assert.strictEqual(c, false)
                          assert.strictEqual(d, false)
                      })
  
                      it(`mixed type A`, () => {
                          const [a, b, c, d] = run([1, '1'], [])
                          assert.strictEqual(a, true)
                          assert.strictEqual(b, true)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
  
                      it(`mixed type B`, () => {
                          const [a, b, c, d] = run([1, '1'], [1, '1'])
                          assert.strictEqual(a, true)
                          assert.strictEqual(b, true)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
  
                      it(`mixed type C`, () => {
                          const [a, b, c, d] = run([1, '1'], ['1', 1])
                          assert.strictEqual(a, true)
                          assert.strictEqual(b, true)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
  
                      it(`mixed type D`, () => {
                          const [a, b, c, d] = run([1, '1'], [1, 1, '1', '1'])
                          assert.strictEqual(a, true)
                          assert.strictEqual(b, true)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
  
                      it(`mixed type E`, () => {
                          const [a, b, c, d] = run([1, '1'], [1, 1, 1])
                          assert.strictEqual(a, true)
                          assert.strictEqual(b, true)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
  
                      it(`mixed type F`, () => {
                          const [a, b, c, d] = run([1, '1'], ['1', '1', '1'])
                          assert.strictEqual(a, true)
                          assert.strictEqual(b, true)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
  
                      it(`mixed type A - incompatible`, () => {
                          const [a, b, c, d] = run([1, '1'], [true])
                          assert.strictEqual(a, false)
                          assert.strictEqual(b, false)
                          assert.strictEqual(c, false)
                          assert.strictEqual(d, false)
                      })
  
                      it(`mixed type B - incompatible`, () => {
                          const [a, b, c, d] = run([1, '1'], [1, '1', true])
                          assert.strictEqual(a, false)
                          assert.strictEqual(b, false)
                          assert.strictEqual(c, false)
                          assert.strictEqual(d, false)
                      })
  
                      it(`mixed type C - incompatible`, () => {
                          const [a, b, c, d] = run([1, '1'], [true, 1, '1'])
                          assert.strictEqual(a, false)
                          assert.strictEqual(b, false)
                          assert.strictEqual(c, false)
                          assert.strictEqual(d, false)
                      })
  
                      it(`mixed type D - incompatible`, () => {
                          const [a, b, c, d] = run([1, '1'], ['1', true, 1])
                          assert.strictEqual(a, false)
                          assert.strictEqual(b, false)
                          assert.strictEqual(c, false)
                          assert.strictEqual(d, false)
                      })
  
                      it(`mixed type E - incompatible`, () => {
                          const [a, b, c, d] = run([1, '1'], [true, true, true])
                          assert.strictEqual(a, false)
                          assert.strictEqual(b, false)
                          assert.strictEqual(c, false)
                          assert.strictEqual(d, false)
                      })
                  })
  
                  describe('nested', () => {
                      it(`object`, () => {
                          const [a, b, c, d] = run([{ a: 1 }], [{ a: 2 }])
                          assert.strictEqual(a, true)
                          assert.strictEqual(b, true)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
                      it(`object - incompatible`, () => {
                          const [a, b, c, d] = run([{ a: 1 }], [{ a: '1' }])
                          assert.strictEqual(a, false)
                          assert.strictEqual(b, false)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
  
                      it(`array`, () => {
                          const [a, b, c, d] = run([[1]], [[9]])
                          assert.strictEqual(a, true)
                          assert.strictEqual(b, true)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
                      it(`array - incompatible`, () => {
                          const [a, b, c, d] = run([[1]], [['']])
                          assert.strictEqual(a, false)
                          assert.strictEqual(b, false)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
  
                      it(`mixed type A`, () => {
                          const [a, b, c, d] = run([{ a: 1 }, { a: '' }], [{ a: 9 }])
                          assert.strictEqual(a, true)
                          assert.strictEqual(b, true)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
  
                      it(`mixed type B`, () => {
                          const [a, b, c, d] = run([{ a: 1 }, { a: '' }], [{ a: '9' }])
                          assert.strictEqual(a, true)
                          assert.strictEqual(b, true)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
  
                      it(`mixed type C`, () => {
                          const [a, b, c, d] = run([{ a: 1 }, { a: '' }], [{ a: 9 }, { a: '9' }])
                          assert.strictEqual(a, true)
                          assert.strictEqual(b, true)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
  
                      it(`mixed type D`, () => {
                          const [a, b, c, d] = run([{ a: 1 }, { a: '' }], [{ a: '9' }, { a: 9 }])
                          assert.strictEqual(a, true)
                          assert.strictEqual(b, true)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
  
                      it(`mixed type F`, () => {
                          const [a, b, c, d] = run([{ a: 1 }, { a: '' }], [{ a: 9 }, { a: 9 }])
                          assert.strictEqual(a, true)
                          assert.strictEqual(b, true)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
  
                      it(`mixed type E`, () => {
                          const [a, b, c, d] = run([{ a: 1 }, { a: '' }], [{ a: '9' }, { a: '9' }])
                          assert.strictEqual(a, true)
                          assert.strictEqual(b, true)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
  
                      it(`mixed type A - incompatible`, () => {
                          const [a, b, c, d] = run([{ a: 1 }, { a: '' }], [{}])
                          assert.strictEqual(a, false)
                          assert.strictEqual(b, false)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
  
                      it(`mixed type B - incompatible`, () => {
                          const [a, b, c, d] = run([{ a: 1 }, { a: '' }], [{ b: 9 }])
                          assert.strictEqual(a, false)
                          assert.strictEqual(b, false)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
  
                      it(`mixed type C - incompatible`, () => {
                          const [a, b, c, d] = run([{ a: 1 }, { a: '' }], [{ a: true }])
                          assert.strictEqual(a, false)
                          assert.strictEqual(b, false)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
  
                      it(`mixed type D - incompatible`, () => {
                          const [a, b, c, d] = run([{ a: 1 }, { a: '' }], [{ a: true }, { a: true }])
                          assert.strictEqual(a, false)
                          assert.strictEqual(b, false)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
  
                      it(`mixed type F - incompatible`, () => {
                          const [a, b, c, d] = run([{ a: 1 }, { a: '' }], [{ a: true }, { a: 9 }])
                          assert.strictEqual(a, false)
                          assert.strictEqual(b, false)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
  
                      it(`mixed type E - incompatible`, () => {
                          const [a, b, c, d] = run([{ a: 1 }, { a: '' }], [{ a: true }, { a: '9' }])
                          assert.strictEqual(a, false)
                          assert.strictEqual(b, false)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
  
                      it(`mixed type F - incompatible`, () => {
                          const [a, b, c, d] = run([{ a: 1 }, { a: '' }], [{ a: 9 }, { a: true }])
                          assert.strictEqual(a, false)
                          assert.strictEqual(b, false)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
  
                      it(`mixed type G - incompatible`, () => {
                          const [a, b, c, d] = run([{ a: 1 }, { a: '' }], [{ a: '9' }, { a: true }])
                          assert.strictEqual(a, false)
                          assert.strictEqual(b, false)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
  
                      it(`mixed type H - incompatible`, () => {
                          const [a, b, c, d] = run([{ a: 1 }, { a: '' }], [{ a: 9 }, { a: '9' }, { a: true }])
                          assert.strictEqual(a, false)
                          assert.strictEqual(b, false)
                          assert.strictEqual(c, true)
                          assert.strictEqual(d, true)
                      })
                  })
              })
          })
      })
  })
  