1

I'm trying to write a leap year algorithm with a TDD suite. This is my first real attempt in working with TDD.

This is the code from the spec file.

var Year = require('./leap');

describe('Leap year', function() {

  it('is not very common', function() {
    var year = new Year(2015);
    expect(year.isLeap()).toBe(false);
  });

  it('is introduced every 4 years to adjust about a day', function() {
    var year = new Year(2016);
    expect(year.isLeap()).toBe(true);
  });

  it('is skipped every 100 years to remove an extra day', function() {
    var year = new Year(1900);
    expect(year.isLeap()).toBe(false);
  });

  it('is reintroduced every 400 years to adjust another day', function() {
    var year = new Year(2000);
    expect(year.isLeap()).toBe(true);
  });

This is the code so far from the leap.js file

var leapYear = function() {};

leapYear.prototype.isLeap = function(year) {
  if (year % 4 != 0) {
    return true;
  }
}

module.exports = leapYear;

I keep getting:

Failures:

1) Leap year is not very common Message: Expected true to be false. Stacktrace: Error: Expected true to be false. at null.

2) Leap year is skipped every 100 years to remove an extra day Message: Expected true to be false. Stacktrace: Error: Expected true to be false. at null.

Finished in 0.014 seconds 4 tests, 4 assertions, 2 failures, 0 skipped

Any ideas?

Timoor Kurdi
  • 65
  • 1
  • 6

2 Answers2

2

It should be as simple as:

var leapYear = function(year) {this.year = year};

leapYear.prototype.isLeap = function() {
  return this.year % 4 == 0 && this.year % 100 != 0 || this.year % 400 == 0;
}

module.exports = leapYear;

If the year ends with 00 (in another word, year % 100 == 0), u should check if it can be divided by 400. Other wise just check if it can be divided by 4.

Edit:

Explanation:

First the code

  • The test case wants a year object that constructs with a integer, hence your leapYear 'class' should take in a integer when constructing, and store it as a member variable.
  • The isLeap function takes no argument, hence yours shouldn't take any argument as well, it uses the year it get when constructing this object.

Then the math

  • 1st test case simply mean if a year can't be divided by 4, it is not a leap year.
  • 2nd test case means if a year can be divided by 4, it is a leap year
  • 3rd test case means if a year can be divided by 4, but ends with 00(every 100 year), it is not a leap year.
  • 4th test case means if a year can be divided by 4, ends with 00, and can be divided by 400, it is a leap year.

Combining all these we know:

  1. A year that cannot be divided by 4 is never a leap year.
  2. A year that can be divided by 400 must be a leap year.
  3. A year that can be divided by 4 is a leap year if it cannot be divided 100

so if you just test all these 3 case one by one, then u get your answer

rabbit.aaron
  • 2,369
  • 16
  • 25
  • Failures: 1) Leap year is introduced every 4 years to adjust about a day Message: Expected false to be true. Stacktrace: Error: Expected false to be true. at null. 2) Leap year is reintroduced every 400 years to adjust another day Message: Expected false to be true. Stacktrace: Error: Expected false to be true. at null. Finished in 0.013 seconds 4 tests, 4 assertions, 2 failures, 0 skipped. That's what I get when I tried your code. – Timoor Kurdi Feb 29 '16 at 01:28
0
  • year % 4 != 0 in non-leap years (2013, 2014, 2015).
  • You have no code yet to account for the 100-year and 400-year case.
  • EDIT: As charlieftl says, .toBe(false) will not be satisfied.
Amadan
  • 191,408
  • 23
  • 240
  • 301
  • There is no function like `isLeap` on `Date`, but internally, yes, it does. `new Date("1900/02/29").getDate()` says `1`, `new Date("2016/02/29").getDate()` says `29`. – Amadan Feb 29 '16 at 00:38
  • just curious..have used it but never reaching out or back very far – charlietfl Feb 29 '16 at 00:39