ekkis
ekkis

Reputation: 10226

Isn't the Array object different from the Object (thought typeof on both returns the same value)?

two of these tests fail. can anyone explain why and how to fix it?

var assert = require('assert').strict

Number.prototype.isNbr = true
Number.prototype.isStr = false
Number.prototype.isObj = false
Number.prototype.isArr = false

String.prototype.isNbr = false
String.prototype.isStr = true
String.prototype.isObj = false
String.prototype.isArr = false

Array.prototype.isNbr = false
Array.prototype.isStr = false
Array.prototype.isObj = false
Array.prototype.isArr = true

Object.prototype.isNbr = false
Object.prototype.isStr = false
Object.prototype.isObj = true
Object.prototype.isArr = false

describe('Number', () => {
    var x = 0;
    it('Is number', () => { assert.ok(x.isNbr) })
    it('Is string', () => { assert.ok(!x.isStr) })
    it('Is object', () => { assert.ok(!x.isObj) })
    it('Is array', () => { assert.ok(!x.isObj) })
})

describe('String', () => {
    var x = ''; 
    it('Is number', () => { assert.ok(!x.isNbr) })
    it('Is string', () => { assert.ok(x.isStr) })
    it('Is object', () => { assert.ok(!x.isObj) })
    it('Is array', () => { assert.ok(!x.isObj) })
})

describe('Object', () => {
    var x = {}; 
    it('Is number', () => { assert.ok(!x.isNbr) })
    it('Is string', () => { assert.ok(!x.isStr) })
    it('Is object', () => { assert.ok(x.isObj) })
    it('Is array', () => { assert.ok(!x.isObj) })
})

describe('Array', () => {
    var x = []; 
    it('Is number', () => { assert.ok(!x.isNbr) })
    it('Is string', () => { assert.ok(!x.isStr) })
    it('Is object', () => { assert.ok(!x.isObj) })
    it('Is array', () => { assert.ok(x.isObj) })
})

You can save to a file t.js and run like this:

$ mocha t.js

edit I

corrected line

var x = [];

which @MarkMeyer pointed out was wrong. in my original it was correct and correcting it doesn't change the results

Upvotes: 0

Views: 73

Answers (2)

Intervalia
Intervalia

Reputation: 10945

To test for an array use Array.isArray(val):

var a = [1,2,3];
var b = {a:1};

console.log(Array.isArray(a));
console.log(Array.isArray(b));

The biggest reason your code was failing was because you were not calling .isArr. Look back at your code. You are calling .isObj twice in each.

var assert = {
  ok(val) {
    if (!val) {
      console.error(`The value ${val} was not true.`);
    }
    else {
      console.info('     ✓');
    }
  }
}

function describe(text, fn) {
  console.log(`Running test for: ${text}`);
  fn();
}

function it(text, fn) {
  console.log(`  -- ${text}`);
  fn();
}

Number.prototype.isNbr = true
Number.prototype.isStr = false
Number.prototype.isObj = false
Number.prototype.isArr = false

String.prototype.isNbr = false
String.prototype.isStr = true
String.prototype.isObj = false
String.prototype.isArr = false

Array.prototype.isNbr = false
Array.prototype.isStr = false
Array.prototype.isObj = false
Array.prototype.isArr = true

Object.prototype.isNbr = false
Object.prototype.isStr = false
Object.prototype.isObj = true
Object.prototype.isArr = false

describe('Number', () => {
    var x = 0;
    it('Is number', () => { assert.ok(x.isNbr) })
    it('Is string', () => { assert.ok(!x.isStr) })
    it('Is object', () => { assert.ok(!x.isObj) })
    it('Is array', () => { assert.ok(!x.isArr) })
})

describe('String', () => {
    var x = ''; 
    it('Is number', () => { assert.ok(!x.isNbr) })
    it('Is string', () => { assert.ok(x.isStr) })
    it('Is object', () => { assert.ok(!x.isObj) })
    it('Is array', () => { assert.ok(!x.isArr) })
})

describe('Object', () => {
    var x = {}; 
    it('Is number', () => { assert.ok(!x.isNbr) })
    it('Is string', () => { assert.ok(!x.isStr) })
    it('Is object', () => { assert.ok(x.isObj) })
    it('Is array', () => { assert.ok(!x.isArr) })
})

describe('Array', () => {
    var x = []; 
    it('Is number', () => { assert.ok(!x.isNbr) })
    it('Is string', () => { assert.ok(!x.isStr) })
    it('Is object', () => { assert.ok(!x.isObj) })
    it('Is array', () => { assert.ok(x.isArr) })
})

But this is not the best way to test these types. You are changing the prototype of built in objects. That is generally considered a bad practice.

You could do this:

var assert = {
  ok(val) {
    if (!val) {
      console.error(`The value ${val} was not true.`);
    }
    else {
      console.info('     ✓');
    }
  }
}

function describe(text, fn) {
  console.log(`Running test for: ${text}`);
  fn();
}

function it(text, fn) {
  console.log(`  -- ${text}`);
  fn();
}

const isNbr = val => Object.prototype.toString.apply(val).slice(8,-1) === 'Number'
const isStr = val => Object.prototype.toString.apply(val).slice(8,-1) === 'String';
const isFun = val => Object.prototype.toString.apply(val).slice(8,-1) === 'Function';
const isObj = val => Object.prototype.toString.apply(val).slice(8,-1) === 'Object';
const isArr = val => Array.isArray(val);

describe('Number', () => {
    var x = 0;
    it('Is number', () => { assert.ok(isNbr(x)) })
    it('Is string', () => { assert.ok(!isStr(x)) })
    it('Is object', () => { assert.ok(!isObj(x)) })
    it('Is function', () => { assert.ok(!isFun(x)) })
    it('Is array', () => { assert.ok(!isArr(x)) })
})

describe('Function', () => {
    var x = () => {};
    it('Is number', () => { assert.ok(!isNbr(x)) })
    it('Is string', () => { assert.ok(!isStr(x)) })
    it('Is object', () => { assert.ok(!isObj(x)) })
    it('Is function', () => { assert.ok(isFun(x)) })
    it('Is array', () => { assert.ok(!isArr(x)) })
})

describe('String', () => {
    var x = ''; 
    it('Is number', () => { assert.ok(!isNbr(x)) })
    it('Is string', () => { assert.ok(isStr(x)) })
    it('Is object', () => { assert.ok(!isObj(x)) })
    it('Is function', () => { assert.ok(!isFun(x)) })
    it('Is array', () => { assert.ok(!isArr(x)) })
})

describe('Object', () => {
    var x = {}; 
    it('Is number', () => { assert.ok(!isNbr(x)) })
    it('Is string', () => { assert.ok(!isStr(x)) })
    it('Is object', () => { assert.ok(isObj(x)) })
    it('Is function', () => { assert.ok(!isFun(x)) })
    it('Is array', () => { assert.ok(!isArr(x)) })
})

describe('Array', () => {
    var x = []; 
    it('Is number', () => { assert.ok(!isNbr(x)) })
    it('Is string', () => { assert.ok(!isStr(x)) })
    it('Is object', () => { assert.ok(!isObj(x)) })
    it('Is function', () => { assert.ok(!isFun(x)) })
    it('Is array', () => { assert.ok(isArr(x)) })
})

describe('Null', () => {
    var x = null; 
    it('Is number', () => { assert.ok(!isNbr(x)) })
    it('Is string', () => { assert.ok(!isStr(x)) })
    it('Is object', () => { assert.ok(!isObj(x)) })
    it('Is function', () => { assert.ok(!isFun(x)) })
    it('Is array', () => { assert.ok(!isArr(x)) })
})

Upvotes: 0

ekkis
ekkis

Reputation: 10226

as @Paulpro cleverly pointed out, my tests are bad. I was checking for .isObj where I should have been checking for .isArr

if I fix that everything works

Upvotes: 1

Related Questions