More documentation and tests
diff --git a/dev/js/runner/datepicker.html b/dev/js/runner/datepicker.html
new file mode 100644
index 0000000..141d7c6
--- /dev/null
+++ b/dev/js/runner/datepicker.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Spec Runner for the DatePicker</title>
+  <link rel="shortcut icon" type="image/png" href="../lib/jasmine-2.1.1/jasmine_favicon.png">
+  <link rel="stylesheet" href="../lib/jasmine-2.1.1/jasmine.css">
+  <script src="../lib/require.js"></script>
+  <script src="../lib/jasmine-2.1.1/jasmine.js"></script>
+  <script src="../lib/jasmine-2.1.1/jasmine-html.js"></script>
+  <script src="../lib/jasmine-2.1.1/boot.js"></script>
+  <script>
+    require.config({
+      baseUrl: "../src",
+      paths: {
+        "lib" : "../lib",
+        "spec" : "../spec"
+      }
+    });
+    require([
+      'lib/domReady!',
+      'spec/datepickerSpec'
+    ],
+    function () {
+      if (jsApiReporter.finished === true)
+        jasmine.getEnv().execute();
+    });
+  </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/dev/js/spec/datepickerSpec.js b/dev/js/spec/datepickerSpec.js
new file mode 100644
index 0000000..bcab225
--- /dev/null
+++ b/dev/js/spec/datepickerSpec.js
@@ -0,0 +1,84 @@
+define(['datepicker'], function (dpClass) {
+  describe('KorAP.Datepicker', function () {
+
+    it('should be initializable', function () {
+      var dp = dpClass.create();
+      var e = dp.show();
+      expect(e.nodeName).toEqual('DIV');
+      expect(e.classList.contains('datepicker')).toBeTruthy();
+      expect(e.getAttribute('tabindex')).toEqual('0');
+    });
+
+    it('should generate valid dates', function () {
+      var dp = dpClass.create();
+      expect(dp.today()).toMatch("\\d{4}-[01\\d-[01]\\d");
+    });    
+
+    it('should have year and month helpers', function () {
+      var dp = dpClass.create();
+      var e = dp.show(2013, 2);
+      expect(e.nodeName).toEqual('DIV');
+      expect(e.classList.contains('datepicker')).toBeTruthy();
+      expect(e.getAttribute('tabindex')).toEqual('0');
+      expect(e.querySelector('div.year > span:nth-child(2)').firstChild.data).toEqual('2013');
+      expect(e.querySelector('div.month > span:nth-child(2)').firstChild.data).toEqual('February');
+    });
+
+    it('should have modifyable year', function () {
+      var dp = dpClass.create();
+      var e = dp.show(2013, 2);
+      expect(e.nodeName).toEqual('DIV');
+      expect(e.classList.contains('datepicker')).toBeTruthy();
+      expect(e.getAttribute('tabindex')).toEqual('0');
+      expect(e.querySelector('div.year > span:nth-child(2)').firstChild.data).toEqual('2013');
+      expect(e.querySelector('div.month > span:nth-child(2)').firstChild.data).toEqual('February');
+
+      dp.incrYear();
+      expect(e.querySelector('div.year > span:nth-child(2)').firstChild.data).toEqual('2014');
+      expect(e.querySelector('div.month > span:nth-child(2)').firstChild.data).toEqual('February');
+
+      dp.incrYear();
+      expect(e.querySelector('div.year > span:nth-child(2)').firstChild.data).toEqual('2015');
+      expect(e.querySelector('div.month > span:nth-child(2)').firstChild.data).toEqual('February');
+
+      dp.decrYear();
+      expect(e.querySelector('div.year > span:nth-child(2)').firstChild.data).toEqual('2014');
+      expect(e.querySelector('div.month > span:nth-child(2)').firstChild.data).toEqual('February');
+
+      // Max value
+      var e = dp.show(9998, 2);
+      expect(e.querySelector('div.year > span:nth-child(2)').firstChild.data).toEqual('9998');
+      expect(e.querySelector('div.month > span:nth-child(2)').firstChild.data).toEqual('February');
+
+      dp.incrYear();
+      expect(e.querySelector('div.year > span:nth-child(2)').firstChild.data).toEqual('9999');
+      expect(e.querySelector('div.month > span:nth-child(2)').firstChild.data).toEqual('February');
+
+      dp.incrYear();
+      expect(e.querySelector('div.year > span:nth-child(2)').firstChild.data).toEqual('9999');
+      expect(e.querySelector('div.month > span:nth-child(2)').firstChild.data).toEqual('February');
+
+      // Min value
+      var e = dp.show(2, 2);
+      expect(e.querySelector('div.year > span:nth-child(2)').firstChild.data).toEqual('2');
+      expect(e.querySelector('div.month > span:nth-child(2)').firstChild.data).toEqual('February');
+
+      dp.decrYear();
+      expect(e.querySelector('div.year > span:nth-child(2)').firstChild.data).toEqual('1');
+      expect(e.querySelector('div.month > span:nth-child(2)').firstChild.data).toEqual('February');
+
+      dp.decrYear();
+      expect(e.querySelector('div.year > span:nth-child(2)').firstChild.data).toEqual('0');
+      expect(e.querySelector('div.month > span:nth-child(2)').firstChild.data).toEqual('February');
+
+      dp.decrYear();
+      expect(e.querySelector('div.year > span:nth-child(2)').firstChild.data).toEqual('0');
+      expect(e.querySelector('div.month > span:nth-child(2)').firstChild.data).toEqual('February');
+    });
+
+    it('should have modifyable month', function () {
+      var dp = dpClass.create();
+      var e = dp.show(2013, 6);
+    });
+  });
+});
diff --git a/dev/js/src/datepicker.js b/dev/js/src/datepicker.js
index 8608efe..9882364 100644
--- a/dev/js/src/datepicker.js
+++ b/dev/js/src/datepicker.js
@@ -39,6 +39,7 @@
       return this;
     },
 
+
     /**
      * Get or select a specific date.
      */
@@ -80,6 +81,7 @@
       this._click = cb;
     },
 
+
     /**
      * Show the datepicker.
      * Will either show the selected year/month
@@ -111,6 +113,7 @@
       return this._element;
     },
 
+
     /**
      * Get the HTML element associated with the datepicker.
      */
@@ -118,6 +121,7 @@
       return this._element;
     },
 
+
     /**
      * Get the current date in string format.
      */
@@ -131,28 +135,37 @@
       return str;
     },
 
+
     /**
      * Increment the year.
      */
     incrYear : function () {
-      this._showYear++;
-      this._updateYear();
-      this._updateMonth();
-      this._updateDay();
+      if (this._showYear < 9999) {
+	this._showYear++;
+	this._updateYear();
+	this._updateMonth();
+	this._updateDay();
+	return this;
+      };
       return;
     },
 
+
     /**
      * Decrement the year.
      */
     decrYear : function () {
-      this._showYear--;
-      this._updateYear();
-      this._updateMonth();
-      this._updateDay();
+      if (this._showYear > 0) {
+	this._showYear--;
+	this._updateYear();
+	this._updateMonth();
+	this._updateDay();
+	return this;
+      };
       return;
     },
 
+
     /**
      * Increment the month.
      */
@@ -166,8 +179,10 @@
 	this._updateMonth();
 	this._updateDay();
       };
+      return this;
     },
 
+
     /**
      * Decrement the month.
      */
@@ -181,6 +196,8 @@
 	this._updateMonth();
 	this._updateDay();
       };
+
+      return this;
     },