Search code examples
javascriptjasmine-node

JavaScript code does not pass Jasmine toThrow test


I am learning JavaScript and Jasmine-Node I have successfully passed the first 11 matchers. But I can't seem to get past this toThrow matcher and I have looked up everything I can think of to get past it. I am stuck. I would really appreciate some help and any comments on my code in general are welcome too.

Here is the spec test...

var Triangle = require('./triangle');

describe('Triangle', function() {

  it('equilateral triangles have equal sides', function() {
    var triangle = new Triangle(2,2,2);
    expect(triangle.kind()).toEqual('equilateral');
  });

  it('larger equilateral triangles also have equal sides', function() {
    var triangle = new Triangle(10,10,10);
    expect(triangle.kind()).toEqual('equilateral');
  });

  it('isosceles triangles have last two sides equal', function() {
    var triangle = new Triangle(3,4,4);
    expect(triangle.kind()).toEqual('isosceles');
  });

  it('isosceles trianges have first and last sides equal', function() {
    var triangle = new Triangle(4,3,4);
    expect(triangle.kind()).toEqual('isosceles');
  });

  it('isosceles triangles have two first sides equal', function() {
    var triangle = new Triangle(4,4,3);
    expect(triangle.kind()).toEqual('isosceles');
  });

  it('isosceles triangles have in fact exactly two sides equal', function() {
    var triangle = new Triangle(10,10,2);
    expect(triangle.kind()).toEqual('isosceles');
  });

  it('scalene triangles have no equal sides', function() {
    var triangle = new Triangle(3,4,5);
    expect(triangle.kind()).toEqual('scalene');
  });

  it('scalene triangles have no equal sides at a larger scale too', function() {
    var triangle = new Triangle(10,11,12);
    expect(triangle.kind()).toEqual('scalene');
  });

  it('scalene triangles have no equal sides in descending order either', function() {
    var triangle = new Triangle(5,4,2);
    expect(triangle.kind()).toEqual('scalene');
  });

  it('very small triangles are legal', function() {
    var triangle = new Triangle(0.4,0.6,0.3);
    expect(triangle.kind()).toEqual('scalene');
  });

  it('test triangles with no size are illegal', function() {
    var triangle = new Triangle(0,0,0);
    expect(triangle.kind.bind(triangle)).toThrow();
  });

  xit('triangles with negative sides are illegal', function() {
    var triangle = new Triangle(3,4,-5);
    expect(triangle.kind.bind(triangle)).toThrow();
  });

  xit('triangles violating triangle inequality are illegal', function() {
    var triangle = new Triangle(1,1,3);
    expect(triangle.kind.bind(triangle)).toThrow();
  });

  xit('edge cases of triangle inequality are in fact legal', function() {
    var triangle = new Triangle(2,4,2);
    expect(triangle.kind.bind(triangle)).not.toThrow();
  });

  xit('triangles violating triangle inequality are illegal 2', function() {
    var triangle = new Triangle(7,3,2);
    expect(triangle.kind.bind(triangle)).toThrow();
  });

  xit('triangles violating triangle inequality are illegal 3', function() {
    var triangle = new Triangle(10,1,3);
    expect(triangle.kind.bind(triangle)).toThrow();
  });

});

This is my JavaScript...

function Triangle(sideA, sideB, sideC) {

    this.kind = function() {
        //
        // Your solution to the exercise goes here
        //
      var triangleType = "";  
      if (this.isValidTriangle()){
        if (sideA == sideB && sideB == sideC ) {
          triangleType="equilateral";
        }
        else if (sideA == sideB || sideB == sideC || sideA == sideC) {
          triangleType="isosceles";
        }
        else {
         triangleType="scalene";
        } 
      }
      else {
//          throw new Error('Invalid Triangle');
//          throw TypeError("Invalid Triangle");
//          throw "up";
          throw new RangeError("Test");
          } 
      return triangleType;    
    };
    this.isValidTriangle = function() {
        var sides = [sideA, sideB, sideC];
        for(var i = 0; i < sides.length; i++) {
            if(sides[i] = 0) {i = 3; return false;};
        };
        return true;
    };
};

module.exports = Triangle;

This is the Jasmine output...

c:\Users\EP\exercism\javascript>jasmine-node triangle --verbose

Triangle - 20 ms
    equilateral triangles have equal sides - 16 ms
    larger equilateral triangles also have equal sides - 1 ms
    isosceles triangles have last two sides equal - 0 ms
    isosceles trianges have first and last sides equal - 0 ms
    isosceles triangles have two first sides equal - 0 ms
    isosceles triangles have in fact exactly two sides equal - 0 ms
    scalene triangles have no equal sides - 0 ms
    scalene triangles have no equal sides at a larger scale too - 0 ms
    scalene triangles have no equal sides in descending order either - 0 ms
    very small triangles are legal - 0 ms
    test triangles with no size are illegal - 1 ms

Failures:

  1) Triangle test triangles with no size are illegal
   Message:
     Expected function to throw an exception.
   Stacktrace:
     Error: Expected function to throw an exception.
    at null.<anonymous> (C:\Users\EP\exercism\javascript\triangle\triangle.spec.js:57:42)

Finished in 0.053 seconds
11 tests, 11 assertions, 1 failure, 0 skipped

I know I must be missing something. I have read Jasmine doc, JavaScript doc, MDN, googled it and just can't seem to determine what I am doing wrong.

Update: with some help from the stackoverflow community I was able to overcome the issue. Below is the final code which passed all of the matchers (those that were pending (xit) were all activated (it).

function Triangle(sideA, sideB, sideC) {

    this.kind = function() {
        //
        // Your solution to the exercise goes here
        //
      if (this.isValidTriangle() == false){ throw new TypeError("Invalid Triangle");}
      else if (sideA == sideB && sideB == sideC ) {
        triangleType="equilateral";
      }
      else if (sideA == sideB || sideB == sideC || sideA == sideC) {
        triangleType="isosceles";
      }
      else {
        triangleType="scalene";
      }
      return triangleType; 
    };

    this.isValidTriangle = function() {
        // no triangle inequality
        if(sideA + sideB < sideC) {return false;}
        if(sideB + sideC < sideA) {return false;}
        if(sideA + sideC < sideB) {return false;}       
        // no zero or negative sides
        var sides = [sideA, sideB, sideC];
        for(var i = 0; i < 3; i++) {
            if(sides[i] <= 0) {i = 3; return false;}; 
        };
        return true;
    };
}
module.exports = Triangle;

Thanks again to all who helped me with their answers!


Solution

  • The bind method returns a function statement. You can't expect function statement to throw an exception before you execute it. If you want to change the context and execute the function at the same time you need to use apply or call.