Tests failing due to compare method added to Array prototype. How can I update the code or the tests?

StackOverflow https://stackoverflow.com/questions/23508983

  •  16-07-2023
  •  | 
  •  

سؤال

I'm diving into the Mars Rover Kata. I'm running into an interesting problem. My jasmine tests are failing due to my array compare method in the prototype. I'm using the array compare method to detect obstacles at a specified coordinate or grid point.

As an example my first test produces this error: Expected [ 0, 1, 'N', undefined ] to equal [ 0, 1, 'N' ].

When I console.log my array I get: [0, 1, "N", compare: function]. This explains why it's not equal to [0, 1, 'N'].

The length of my array is 3 and the proto has the compare method. What can I do about this issue?

Here is the branch/code. Here are the tests.

Update:

It turns out that one of my conditionals was returning undefined which was causing my error of undefined being pushed into my array, but without trying @GameAlchemist solution I wouldn't have learned about defineProperty or figured out the problem.

In addition, from what I've read it is good practice when adding properties to built-in prototypes to use Object.defineProperty() and similar methods to make them non-enumerable. That will give you some protection against breaking for-in loops in legacy code.

هل كانت مفيدة؟

المحلول

You can use Object.defineProperty to hide a prototype property/method by setting it as non-enumerable.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

So if you're the one defining compare, do it like :

Object.defineProperty(Array.prototype, 'compare', { value : compareFunction } );

Since configurable, enumerable, and writable are false by default, you'll have a readonly, non-configurable and non-enumerable property : it won't stand in the way of your comparisons.

If you're not the one defining compare, you have to hope it is still configurable (look with Object. getOwnPropertyDescriptor or just test the following code) :

Object.defineProperty(Array.prototype, 'compare', { value : Array.prototype.compare } );

In the same way, you can do a loop on all Array prototype to check if every of its own property is enumerable, and set it to non-enumerable if it is.

http://jsbin.com/zunahebo/2/edit?js,console

Object.defineProperty(Array.prototype, 'compare', { value : compareArray } );
function compareArray(other) {
  if (!other || other.length != this.length) return false;
  for (var i=0; i<this.length; i++) if (this[i] !== other[i]) return false;
  return true;
}

var a1 = [1, 2, 3, 4];
var a2 = [1, 2, 3, 4];
var a3 = [1, 2, 5, 6];
var a4 = [1, 2];

console.log(' a1 == a2 : ' + a1.compare(a2));
console.log(' a1 == a3 : ' + a1.compare(a3));
console.log(' a1 == a4 : ' + a1.compare(a4));

نصائح أخرى

perhaps:

for(var i = 0, l=this.length; i < l; i++) {
    if (this.hasOwnProperty(i)){ 
        ... 
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top