You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by on...@apache.org on 2014/01/17 12:59:32 UTC

git commit: AMBARI-4329. Remove Hosts logic from TableView. (onechiporenko)

Updated Branches:
  refs/heads/trunk 207f4bc6f -> 05d9a042f


AMBARI-4329. Remove Hosts logic from TableView. (onechiporenko)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/05d9a042
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/05d9a042
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/05d9a042

Branch: refs/heads/trunk
Commit: 05d9a042f6f9bf18f82fe2f977b72b4906d13aa8
Parents: 207f4bc
Author: Oleg Nechiporenko <on...@apache.org>
Authored: Fri Jan 17 13:56:49 2014 +0200
Committer: Oleg Nechiporenko <on...@apache.org>
Committed: Fri Jan 17 13:56:49 2014 +0200

----------------------------------------------------------------------
 ambari-web/app/assets/test/tests.js             |   2 +-
 ambari-web/app/views/common/table_view.js       | 135 ++++++----
 .../controllers/main/charts/heatmap_test.js     |  29 ++-
 ambari-web/test/mappers/dataset_mapper_test.js  | 109 --------
 ambari-web/test/views/common/table_view_test.js | 257 +++++++++++++++++++
 5 files changed, 364 insertions(+), 168 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/05d9a042/ambari-web/app/assets/test/tests.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/assets/test/tests.js b/ambari-web/app/assets/test/tests.js
index 862919e..8190608 100644
--- a/ambari-web/app/assets/test/tests.js
+++ b/ambari-web/app/assets/test/tests.js
@@ -54,7 +54,6 @@ require('test/installer/step9_test');
 require('test/installer/step10_test');
 require('test/login_test');
 require('test/mappers/server_data_mapper_test');
-require('test/mappers/dataset_mapper_test');
 require('test/mappers/hosts_mapper_test');
 require('test/mappers/jobs_mapper_test');
 require('test/mappers/runs_mapper_test');
@@ -76,6 +75,7 @@ require('test/utils/string_utils_test');
 require('test/utils/lazy_loading_test');
 require('test/views/common/chart/linear_time_test');
 require('test/views/common/filter_view_test');
+require('test/views/common/table_view_test');
 require('test/views/common/quick_link_view_test');
 require('test/views/main/dashboard_test');
 require('test/views/main/dashboard/widget_test');

http://git-wip-us.apache.org/repos/asf/ambari/blob/05d9a042/ambari-web/app/views/common/table_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/table_view.js b/ambari-web/app/views/common/table_view.js
index d1514db..c97b2ea 100644
--- a/ambari-web/app/views/common/table_view.js
+++ b/ambari-web/app/views/common/table_view.js
@@ -24,15 +24,19 @@ App.TableView = Em.View.extend({
 
   /**
    * Shows if all data is loaded and filtered
+   * @type {Boolean}
    */
   filteringComplete: false,
 
   /**
    * Loaded from local storage startIndex value
+   * @type {Number}
    */
   startIndexOnLoad: null,
+
   /**
    * Loaded from server persist value
+   * @type {Number}
    */
   displayLengthOnLoad: null,
 
@@ -81,7 +85,7 @@ App.TableView = Em.View.extend({
   /**
    * Load user preference value on hosts page from server
    */
-  dataLoading: function () {
+  dataLoading: function() {
     var dfd = $.Deferred();
     var self = this;
     this.getUserPref(this.displayLengthKey()).done(function () {
@@ -91,10 +95,15 @@ App.TableView = Em.View.extend({
     });
     return dfd.promise();
   },
+
+  /**
+   * Persist-key of current table displayLength property
+   * @param {String} loginName current user login name
+   * @returns {String}
+   */
   displayLengthKey: function (loginName) {
-    if (!loginName)
-      loginName = App.router.get('loginName');
-    return 'hosts-pagination-displayLength-' + loginName;
+    loginName = loginName ? loginName : App.router.get('loginName');
+    return this.get('controller.name') + '-pagination-displayLength-' + loginName;
   },
 
   /**
@@ -111,41 +120,49 @@ App.TableView = Em.View.extend({
       error: 'getDisplayLengthErrorCallback'
     });
   },
+
+  /**
+   * Set received from server value to <code>displayLengthOnLoad</code>
+   * @param {Number} response
+   * @param {Object} request
+   * @param {Object} data
+   * @returns {*}
+   */
   getDisplayLengthSuccessCallback: function (response, request, data) {
-    if (response != null) {
-      console.log('Got DisplayLength value from server with key ' + data.key + '. Value is: ' + response);
-      this.set('displayLengthOnLoad', response);
-      return response;
-    }
+    console.log('Got DisplayLength value from server with key ' + data.key + '. Value is: ' + response);
+    this.set('displayLengthOnLoad', response);
+    return response;
   },
-  getDisplayLengthErrorCallback: function (request, ajaxOptions, error) {
+
+  /**
+   * Set default value to <code>displayLengthOnLoad</code> (and send it on server) if value wasn't found on server
+   * @returns {Number}
+   */
+  getDisplayLengthErrorCallback: function () {
     // this user is first time login
-    if (request.status == 404) {
-      console.log('Persist did NOT find the key');
-      var displayLengthDefault = 10;
-      this.set('displayLengthOnLoad', displayLengthDefault);
-      this.postUserPref(this.displayLengthKey(), displayLengthDefault);
-      return displayLengthDefault;
-    }
+    console.log('Persist did NOT find the key');
+    var displayLengthDefault = 10;
+    this.set('displayLengthOnLoad', displayLengthDefault);
+    this.postUserPref(this.displayLengthKey(), displayLengthDefault);
+    return displayLengthDefault;
   },
+
   /**
-   * post display length persist key/value to server, value is object
+   * Post display length persist key/value to server
+   * @param {String} key
+   * @param {Object} value
    */
   postUserPref: function (key, value) {
     var keyValuePair = {};
     keyValuePair[key] = JSON.stringify(value);
     App.ajax.send({
-      'name': 'settings.post.user_pref',
-      'sender': this,
-      'beforeSend': 'postUserPrefBeforeSend',
-      'data': {
-        'keyValuePair': keyValuePair
+      name: 'settings.post.user_pref',
+      sender: this,
+      data: {
+        keyValuePair: keyValuePair
       }
     });
   },
-  postUserPrefBeforeSend: function(request, ajaxOptions, data){
-    console.log('BeforeSend to persist: persistKeyValues', data.keyValuePair);
-  },
 
   /**
    * Do pagination after filtering and sorting
@@ -163,7 +180,8 @@ App.TableView = Em.View.extend({
   },
 
   /**
-   * return pagination information displayed on the page
+   * Return pagination information displayed on the page
+   * @type {String}
    */
   paginationInfo: function () {
     return this.t('tableView.filters.paginationInfo').format(this.get('startIndex'), this.get('endIndex'), this.get('filteredContent.length'));
@@ -201,6 +219,10 @@ App.TableView = Em.View.extend({
     }
   }),
 
+  /**
+   * Select View with list of "rows-per-page" options
+   * @type {Ember.View}
+   */
   rowsPerPageSelectView: Em.Select.extend({
     content: ['10', '25', '50'],
     change: function () {
@@ -208,27 +230,28 @@ App.TableView = Em.View.extend({
     }
   }),
 
-  // start index for displayed content on the page
+  /**
+   * Start index for displayed content on the page
+   */
   startIndex: 1,
 
-  // calculate end index for displayed content on the page
+  /**
+   * Calculate end index for displayed content on the page
+   */
   endIndex: function () {
     return Math.min(this.get('filteredContent.length'), this.get('startIndex') + parseInt(this.get('displayLength')) - 1);
   }.property('startIndex', 'displayLength', 'filteredContent.length'),
 
   /**
-   * onclick handler for previous page button on the page
+   * Onclick handler for previous page button on the page
    */
   previousPage: function () {
     var result = this.get('startIndex') - parseInt(this.get('displayLength'));
-    if (result < 2) {
-      result = 1;
-    }
-    this.set('startIndex', result);
+    this.set('startIndex', (result < 2) ? 1 : result);
   },
 
   /**
-   * onclick handler for next page button on the page
+   * Onclick handler for next page button on the page
    */
   nextPage: function () {
     var result = this.get('startIndex') + parseInt(this.get('displayLength'));
@@ -237,10 +260,15 @@ App.TableView = Em.View.extend({
     }
   },
 
-  // the number of rows to show on every page
+  /**
+   * The number of rows to show on every page
+   * @type {Number}
+   */
   displayLength: null,
 
-  // calculates default value for startIndex property after applying filter or changing displayLength
+  /**
+   * Calculates default value for startIndex property after applying filter or changing displayLength
+   */
   updatePaging: function () {
     this.set('startIndex', Math.min(1, this.get('filteredContent.length')));
   }.observes('displayLength', 'filteredContent.length'),
@@ -248,9 +276,9 @@ App.TableView = Em.View.extend({
   /**
    * Apply each filter to each row
    *
-   * @param iColumn number of column by which filter
-   * @param value
-   * @param type
+   * @param {Number} iColumn number of column by which filter
+   * @param {Object} value
+   * @param {String} type
    */
   updateFilter: function (iColumn, value, type) {
     var filterCondition = this.get('filterConditions').findProperty('iColumn', iColumn);
@@ -299,19 +327,27 @@ App.TableView = Em.View.extend({
   },
 
   /**
-   * contain filter conditions for each column
+   * Contain filter conditions for each column
+   * @type {Array}
    */
   filterConditions: [],
 
+  /**
+   * Contains content after implementing filters
+   * @type {Array}
+   */
   filteredContent: [],
 
-  // contain content to show on the current page of data page view
+  /**
+   * Contains content to show on the current page of data page view
+   * @type {Array}
+   */
   pageContent: function () {
     return this.get('filteredContent').slice(this.get('startIndex') - 1, this.get('endIndex'));
   }.property('filteredContent.length', 'startIndex', 'endIndex'),
 
   /**
-   * filter table by filterConditions
+   * Filter table by filterConditions
    */
   filter: function () {
     var content = this.get('content');
@@ -335,8 +371,16 @@ App.TableView = Em.View.extend({
     }
   }.observes('content'),
 
+  /**
+   * Does any filter is used on the page
+   * @type {Boolean}
+   */
   filtersUsed: false,
 
+  /**
+   * Determine if some filters are used on the page
+   * Set <code>filtersUsed</code> value
+   */
   filtersUsedCalc: function() {
     var filterConditions = this.get('filterConditions');
     if (!filterConditions.length) {
@@ -352,6 +396,9 @@ App.TableView = Em.View.extend({
     this.set('filtersUsed', filtersUsed);
   },
 
+  /**
+   * Run <code>clearFilter</code> in the each child filterView
+   */
   clearFilters: function() {
     this.set('filterConditions', []);
     this.get('_childViews').forEach(function(childView) {
@@ -361,4 +408,4 @@ App.TableView = Em.View.extend({
     });
   }
 
-});
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/05d9a042/ambari-web/test/controllers/main/charts/heatmap_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/charts/heatmap_test.js b/ambari-web/test/controllers/main/charts/heatmap_test.js
index 2e51333..399a34c 100644
--- a/ambari-web/test/controllers/main/charts/heatmap_test.js
+++ b/ambari-web/test/controllers/main/charts/heatmap_test.js
@@ -18,6 +18,7 @@
 
 
 var App = require('app');
+require('models/rack');
 require('controllers/main/charts/heatmap');
 
 describe('MainChartsHeatmapController', function () {
@@ -30,15 +31,15 @@ describe('MainChartsHeatmapController', function () {
     it('should set maximumValue if inputMaximum consists only of digits', function () {
       controller.set("inputMaximum", 5);
       expect(controller.get('selectedMetric.maximumValue')).to.equal(5);
-    })
+    });
     it('should not set maximumValue if inputMaximum consists not only of digits', function () {
       controller.set("inputMaximum", 'qwerty');
       expect(controller.get('selectedMetric.maximumValue')).to.equal(5);
-    })
+    });
     it('should not set maximumValue if inputMaximum consists not only of digits', function () {
       controller.set("inputMaximum", '100%');
       expect(controller.get('selectedMetric.maximumValue')).to.equal(5);
-    })
+    });
     it('should set maximumValue if inputMaximum consists only of digits', function () {
       controller.set("inputMaximum", 1000);
       expect(controller.get('selectedMetric.maximumValue')).to.equal(1000);
@@ -56,11 +57,11 @@ describe('MainChartsHeatmapController', function () {
     it('should not set selectedMetric event.context if it is not defined', function () {
       controller.showHeatMapMetric({});
       expect(controller.get('selectedMetric')).to.equal(100);
-    })
+    });
     it('should set selectedMetric event.context if it is defined', function () {
       controller.showHeatMapMetric({context: 5});
       expect(controller.get('selectedMetric')).to.equal(5);
-    })
+    });
   });
 
   describe('#loadMetrics()', function () {
@@ -74,32 +75,32 @@ describe('MainChartsHeatmapController', function () {
       refreshHostSlots: function () {
         controller.set('testPassed', true);
       }
-    }))
+    }));
     controller.loadMetrics();
     it('should set inputMaximum as selectedMetric.maximumValue', function () {
       expect(controller.get('inputMaximum')).to.equal(100);
-    })
+    });
     it('should call refreshHostSlots from selectedMetric', function () {
       expect(controller.get('testPassed')).to.equal(true);
-    })
+    });
   });
 
   describe('#rackClass', function () {
     var controller = App.MainChartsHeatmapController.create({
       allMetrics: [],
-      cluster: {racks: [1]}
+      racks: [1]
     });
     it('should return "span12" for 1 cluster rack', function () {
       expect(controller.get('rackClass')).to.equal('span12');
-    })
+    });
     it('should return "span6" for 2 cluster racks', function () {
-      controller.set('cluster', {racks: [1, 2]});
+      controller.set('racks', [1, 2]);
       expect(controller.get('rackClass')).to.equal('span6');
-    })
+    });
     it('should return "span4" for 3 cluster racks', function () {
-      controller.set('cluster', {racks: [1, 2, 3]});
+      controller.set('racks', [1, 2, 3]);
       expect(controller.get('rackClass')).to.equal('span4');
-    })
+    });
   });
 });
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/05d9a042/ambari-web/test/mappers/dataset_mapper_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/mappers/dataset_mapper_test.js b/ambari-web/test/mappers/dataset_mapper_test.js
deleted file mode 100644
index 886b70f..0000000
--- a/ambari-web/test/mappers/dataset_mapper_test.js
+++ /dev/null
@@ -1,109 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var Ember = require('ember');
-var App = require('app');
-
-require('mappers/server_data_mapper');
-require('mappers/dataset_mapper');
-
-describe('App.dataSetMapper', function () {
-
-  describe('#getId', function() {
-    var tests = [
-      {i:'My Name',e:'My_Name'},
-      {i:'MyName',e:'MyName'},
-      {i:'My  Name',e:'My__Name'},
-      {i:'My Big Name',e:'My_Big_Name'}
-    ];
-    it('Replace spaces with _', function() {
-      tests.forEach(function(test) {
-        expect(App.dataSetMapper.getId(test.i)).to.equal(test.e);
-      });
-    });
-  });
-
-  describe('#parseSchedule', function() {
-    var tests = [
-      {
-        "Feeds":{
-          "frequency":"minutes(1)",
-          "timezone":"UTC",
-          "clusters":{
-            "cluster":[
-              {
-                "name":"drsource3",
-                "type":"source",
-                "validity":{
-                  "start":"2010-01-01T00:00Z",
-                  "end":"2015-01-01T02:00Z"
-                }
-              }
-            ]
-          }
-        },
-        "results": {
-          start_time: '2:0:AM',
-          end_time: '4:0:AM',
-          frequency: 'minutes(1)',
-          timezone: 'UTC',
-          start_date: '1/5/2010',
-          end_date: '1/4/2015'
-        }
-      },
-      {
-        "Feeds":{
-          "frequency":"minutes(5)",
-          "timezone":"UTC",
-          "clusters":{
-            "cluster":[
-              {
-                "name":"drsource3",
-                "type":"source",
-                "validity":{
-                  "start":"2013-01-01T15:00Z",
-                  "end":"2014-01-01T12:00Z"
-                }
-              }
-            ]
-          }
-        },
-        "results": {
-          start_time: '5:0:PM',
-          end_time: '2:0:PM',
-          frequency: 'minutes(5)',
-          timezone: 'UTC',
-          start_date: '1/2/2013',
-          end_date: '1/3/2014'
-        }
-      }
-    ];
-    tests.forEach(function(test) {
-      it('parse valid data', function() {
-        var schedule = App.dataSetMapper.parseSchedule(test);
-        expect(schedule.start_time).to.equal(test.results.start_time);
-        expect(schedule.end_time).to.equal(test.results.end_time);
-        expect(schedule.frequency).to.equal(test.results.frequency);
-        expect(schedule.timezone).to.equal(test.results.timezone);
-        expect(schedule.start_date).to.equal(test.results.start_date);
-        expect(schedule.end_date).to.equal(test.results.end_date);
-      });
-    });
-  });
-
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/05d9a042/ambari-web/test/views/common/table_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/common/table_view_test.js b/ambari-web/test/views/common/table_view_test.js
new file mode 100644
index 0000000..a9f47be
--- /dev/null
+++ b/ambari-web/test/views/common/table_view_test.js
@@ -0,0 +1,257 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+require('utils/db');
+require('views/common/filter_view');
+require('views/common/sort_view');
+require('views/common/table_view');
+
+describe('App.TableView', function () {
+
+  var view;
+
+  beforeEach(function() {
+    App.db.cleanUp();
+  });
+
+  afterEach(function() {
+    App.db.cleanUp();
+  });
+
+  describe('#updatePaging', function() {
+
+    beforeEach(function() {
+      view = App.TableView.create({
+        controller: Em.Object.create({}),
+        displayLength: 10,
+        startIndex: 1,
+        content: d3.range(1, 100),
+        filteredContent: d3.range(1, 100),
+        filtersUsedCalc: function() {},
+        filter: function() {}
+      });
+      view.clearFilters();
+      view.updateFilter();
+    });
+
+    it('should set "startIndex" to 0 if "filteredContent" is empty', function() {
+      view.set('filteredContent', []);
+      expect(view.get('startIndex')).to.equal(0);
+    });
+
+    it('should set "startIndex" to 1 if "filteredContent" is not empty', function() {
+      view.set('filteredContent', d3.range(1, 10));
+      expect(view.get('startIndex')).to.equal(1);
+    });
+
+  });
+
+  describe('#endIndex', function() {
+
+    beforeEach(function() {
+      view = App.TableView.create({
+        controller: Em.Object.create({}),
+        displayLength: 10,
+        startIndex: 1,
+        content: d3.range(1, 100),
+        filteredContent: d3.range(1, 100),
+        filtersUsedCalc: function() {},
+        filter: function() {}
+      });
+      view.clearFilters();
+      view.updateFilter();
+    });
+
+    it('should be recalculated if "startIndex" was changed', function() {
+      view.set('startIndex', 2);
+      expect(view.get('endIndex')).to.equal(11);
+    });
+
+    it('should be recalculated if "displayLength" was changed', function() {
+      view.set('displayLength', 5);
+      expect(view.get('endIndex')).to.equal(5);
+    });
+
+    it('should be recalculated (but not changed) if "filteredContent" was changed (and "filterContent.length" is more than "startIndex + displayLength")', function() {
+      var endIndexBefore = view.get('endIndex');
+      view.set('filteredContent', d3.range(2,100));
+      expect(view.get('endIndex')).to.equal(endIndexBefore);
+    });
+
+    it('should be recalculated (and changed) if "filteredContent" was changed (and "filterContent.length" is less than "startIndex + displayLength")', function() {
+      var endIndexBefore = view.get('endIndex');
+      var indx = 4;
+      view.set('filteredContent', d3.range(1,indx));
+      expect(view.get('endIndex')).to.not.equal(endIndexBefore);
+      expect(view.get('endIndex')).to.equal(indx - 1);
+    });
+
+  });
+
+  describe('#pageContent', function() {
+
+    beforeEach(function() {
+      view = App.TableView.create({
+        controller: Em.Object.create({}),
+        displayLength: 10,
+        startIndex: 1,
+        content: d3.range(1, 100),
+        filteredContent: d3.range(1, 100),
+        endIndex: 10,
+        filtersUsedCalc: function() {},
+        filter: function() {}
+      });
+      view.clearFilters();
+      view.updateFilter();
+    });
+
+    it('should be recalculated if "startIndex" was changed', function() {
+      view.set('startIndex', 2);
+      expect(view.get('pageContent').length).to.equal(9);
+    });
+
+    it('should be recalculated if "endIndex" was changed', function() {
+      view.set('endIndex', 5);
+      expect(view.get('pageContent').length).to.equal(5);
+    });
+
+    it('should be recalculated if "filteredContent" was changed', function() {
+      var pageContentBefore = view.get('pageContent');
+      view.set('filteredContent', d3.range(2,100));
+      expect(view.get('pageContent').length).to.equal(pageContentBefore.length);
+      expect(view.get('pageContent')).to.not.eql(pageContentBefore);
+    });
+
+  });
+
+  describe('#clearFilters', function() {
+
+    it('should set "filterConditions" to empty array', function() {
+      view.clearFilters();
+      expect(view.get('filterConditions')).to.eql([]);
+    });
+
+  });
+
+  describe('#filtersUsedCalc', function() {
+
+    beforeEach(function() {
+      view = App.TableView.create({
+        controller: Em.Object.create({}),
+        displayLength: 10,
+        startIndex: 1,
+        content: d3.range(1, 100),
+        filteredContent: d3.range(1, 100),
+        endIndex: 10,
+        filter: function() {}
+      });
+    });
+
+    it('should set "filtersUsed" to false if "filterConditions" is empty array', function() {
+      view.set('filterConditions', []);
+      view.filtersUsedCalc();
+      expect(view.get('filtersUsed')).to.equal(false);
+    });
+
+    it('should set "filtersUsed" to false if each value in "filterConditions" is empty', function() {
+      view.set('filterConditions', [{value:''}, {value:''}]);
+      view.filtersUsedCalc();
+      expect(view.get('filtersUsed')).to.equal(false);
+    });
+
+    it('should set "filtersUsed" to true if one or more values in "filterConditions" are not empty', function() {
+      view.set('filterConditions', [{value:''}, {value:'lol'}]);
+      view.filtersUsedCalc();
+      expect(view.get('filtersUsed')).to.equal(true);
+    });
+
+  });
+
+  describe('#nextPage', function() {
+
+    beforeEach(function() {
+      view = App.TableView.create({
+        controller: Em.Object.create({}),
+        displayLength: 10,
+        startIndex: 1,
+        content: d3.range(1, 100),
+        filteredContent: d3.range(1, 100),
+        endIndex: 10,
+        filter: function() {}
+      });
+    });
+
+    it('should set "startIndex" if "filteredContent.length is greater than "startIndex" + "displayLength"', function() {
+      var oldStartIndex = view.get('startIndex');
+      var displayLength = 50;
+      view.set('displayLength', displayLength);
+      view.nextPage();
+      expect(view.get('startIndex')).to.equal(oldStartIndex + displayLength);
+    });
+
+    it('should not set "startIndex" if "filteredContent.length is equal to "startIndex" + "displayLength"', function() {
+      var oldStartIndex = view.get('startIndex');
+      var displayLength = 99;
+      view.set('displayLength', displayLength);
+      view.nextPage();
+      expect(view.get('startIndex')).to.equal(oldStartIndex);
+    });
+
+    it('should not set "startIndex" if "filteredContent.length is less than "startIndex" + "displayLength"', function() {
+      var oldStartIndex = view.get('startIndex');
+      var displayLength = 100;
+      view.set('displayLength', displayLength);
+      view.nextPage();
+      expect(view.get('startIndex')).to.equal(oldStartIndex);
+    });
+
+  });
+
+  describe('#previousPage', function() {
+
+    beforeEach(function() {
+      view = App.TableView.create({
+        controller: Em.Object.create({}),
+        displayLength: 10,
+        startIndex: 50,
+        content: d3.range(1, 100),
+        filteredContent: d3.range(1, 100),
+        endIndex: 60,
+        filter: function() {}
+      });
+    });
+
+    it('should set "startIndex" to 1', function() {
+      var displayLength = 50;
+      view.set('displayLength', displayLength);
+      view.previousPage();
+      expect(view.get('startIndex')).to.equal(1);
+    });
+
+    it('should not set "startIndex" to 40', function() {
+      view.set('startIndex', 50);
+      var displayLength = 10;
+      view.set('displayLength', displayLength);
+      view.previousPage();
+      expect(view.get('startIndex')).to.equal(40);
+    });
+
+  });
+
+});