diff options
author | Garren Smith <garren.smith@gmail.com> | 2013-08-21 16:50:35 +0200 |
---|---|---|
committer | Garren Smith <garren.smith@gmail.com> | 2013-08-22 17:39:25 +0200 |
commit | dd2272cef08aac6865bccbc36a786b92ed85ede5 (patch) | |
tree | 0dd86f1f4cf1f79add8c01c2cf443bd12810c716 | |
parent | b65f11ff93223571175d6a9b39e9d55cc9d1bdec (diff) | |
download | couchdb-dd2272cef08aac6865bccbc36a786b92ed85ede5.tar.gz |
Fauxton: Add active task tests
Also improve testing framework
-rw-r--r-- | src/fauxton/Gruntfile.js | 12 | ||||
-rw-r--r-- | src/fauxton/app/addons/activetasks/tests/viewsSpec.js | 139 | ||||
-rw-r--r-- | src/fauxton/app/addons/activetasks/views.js | 41 | ||||
-rw-r--r-- | src/fauxton/test/core/layoutSpec.js | 94 | ||||
-rw-r--r-- | src/fauxton/test/mocha/testUtils.js | 27 | ||||
-rw-r--r-- | src/fauxton/test/runner.html | 1 |
6 files changed, 290 insertions, 24 deletions
diff --git a/src/fauxton/Gruntfile.js b/src/fauxton/Gruntfile.js index 1c58bb649..a548a9d98 100644 --- a/src/fauxton/Gruntfile.js +++ b/src/fauxton/Gruntfile.js @@ -180,8 +180,12 @@ module.exports = function(grunt) { index_css: { src: ["dist/debug/css/*.css", 'assets/css/*.css'], dest: 'dist/debug/css/index.css' - } + }, + test_config_js: { + src: ["dist/debug/templates.js", "test/test.config.js"], + dest: 'test/test.config.js' + } }, cssmin: { @@ -330,12 +334,12 @@ module.exports = function(grunt) { // on watch events configure jshint:all to only run on changed file grunt.event.on('watch', function(action, filepath) { - if (!!filepath.match(/.js$/)) { + if (!!filepath.match(/.js$/) && filepath.indexOf('test.config.js') === -1) { grunt.config(['jshint', 'all'], filepath); } if (!!filepath.match(/[Ss]pec.js$/)) { - grunt.task.run(['mochaSetup','mocha_phantomjs']); + grunt.task.run(['mochaSetup','jst', 'concat:test_config_js', 'mocha_phantomjs']); } }); @@ -381,7 +385,7 @@ module.exports = function(grunt) { */ // clean out previous build artefactsa and lint grunt.registerTask('lint', ['clean', 'jshint']); - grunt.registerTask('test', ['lint', 'mochaSetup', 'mocha_phantomjs']); + grunt.registerTask('test', ['lint', 'mochaSetup','jst', 'concat:test_config_js', 'mocha_phantomjs']); // Fetch dependencies (from git or local dir), lint them and make load_addons grunt.registerTask('dependencies', ['get_deps', 'gen_load_addons:default']); // build templates, js and css diff --git a/src/fauxton/app/addons/activetasks/tests/viewsSpec.js b/src/fauxton/app/addons/activetasks/tests/viewsSpec.js new file mode 100644 index 000000000..395b60a79 --- /dev/null +++ b/src/fauxton/app/addons/activetasks/tests/viewsSpec.js @@ -0,0 +1,139 @@ +// Licensed 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. +define([ + 'api', + 'addons/activetasks/views', + 'addons/activetasks/resources', + 'testUtils' +], function (FauxtonAPI, Views, Models, testUtils) { + var assert = testUtils.assert, + ViewSandbox = testUtils.ViewSandbox; + + describe("TabMenu", function () { + var tabMenu; + + beforeEach(function () { + var newtasks = new Models.Tasks({ + currentView: "all", + id:'activeTasks' + }); + + tabMenu = new Views.TabMenu({ + currentView: "all", + model: newtasks + }); + }); + + describe("on change polling rate", function () { + var viewSandbox; + beforeEach(function () { + viewSandbox = new ViewSandbox(); + viewSandbox.renderView(tabMenu); + }); + + afterEach(function () { + viewSandbox.remove(); + }); + + it("Should set polling rate", function () { + $range = tabMenu.$('#pollingRange'); + $range.val(15); + $range.trigger('change'); + + assert.equal(tabMenu.$('span').text(), 15); + }); + + it("Should clearInterval", function () { + $range = tabMenu.$('#pollingRange'); + clearIntervalMock = sinon.spy(window,'clearInterval'); + $range.trigger('change'); + + assert.ok(clearIntervalMock.calledOnce); + + }); + + it("Should trigger update:poll event", function () { + var spy = sinon.spy(); + Views.Events.on('update:poll', spy); + $range = tabMenu.$('#pollingRange'); + $range.trigger('change'); + + assert.ok(spy.calledOnce); + }); + + }); + + describe('on request by type', function () { + var viewSandbox; + beforeEach(function () { + viewSandbox = new ViewSandbox(); + viewSandbox.renderView(tabMenu); + }); + + afterEach(function () { + viewSandbox.remove(); + }); + + it("should change model view", function () { + var spy = sinon.spy(tabMenu.model, 'changeView'); + var $rep = tabMenu.$('li[data-type="replication"]'); + $rep.click(); + assert.ok(spy.calledOnce); + }); + + it("should set correct active tab", function () { + var spy = sinon.spy(tabMenu.model, 'changeView'); + var $rep = tabMenu.$('li[data-type="replication"]'); + $rep.click(); + assert.ok($rep.hasClass('active')); + }); + + }); + + }); + + describe('DataSection', function () { + var viewSandbox, dataSection; + beforeEach(function () { + var newtasks = new Models.Tasks({ + currentView: "all", + id:'activeTasks' + }); + newtasks.parse([]); + + dataSection = new Views.DataSection({ + currentView: "all", + model: newtasks + }); + + viewSandbox = new ViewSandbox(); + viewSandbox.renderView(dataSection); + }); + + afterEach(function () { + viewSandbox.remove(); + }); + + describe('#setPolling', function () { + + it('Should set polling interval', function () { + var spy = sinon.spy(window, 'setInterval'); + dataSection.setPolling(); + assert.ok(spy.calledOnce); + }); + + }); + + + + }); +}); diff --git a/src/fauxton/app/addons/activetasks/views.js b/src/fauxton/app/addons/activetasks/views.js index 89feff26e..005d48717 100644 --- a/src/fauxton/app/addons/activetasks/views.js +++ b/src/fauxton/app/addons/activetasks/views.js @@ -26,7 +26,7 @@ function (app, FauxtonAPI, activetasks) { }; - _.extend(Events, Backbone.Events); + Views.Events = _.extend(Events, Backbone.Events); Views.TabMenu = FauxtonAPI.View.extend({ template: "addons/activetasks/templates/tabs", @@ -43,11 +43,11 @@ function (app, FauxtonAPI, activetasks) { }; }, afterRender: function(){ - $('.task-tabs').find('li').eq(0).addClass('active'); + this.$('.task-tabs').find('li').eq(0).addClass('active'); }, changePollInterval: function(e){ - var range = $(e.currentTarget).val(); - $('label[for="pollingRange"] span').text(range); + var range = this.$(e.currentTarget).val(); + this.$('label[for="pollingRange"] span').text(range); pollingInfo.rate = range; clearInterval(pollingInfo.intervalId); Events.trigger('update:poll'); @@ -59,33 +59,30 @@ function (app, FauxtonAPI, activetasks) { requestByType: function(e){ var currentTarget = e.currentTarget; - datatype = $(currentTarget).attr("data-type"); + datatype = this.$(currentTarget).attr("data-type"); - $('.task-tabs').find('li').removeClass('active'); - $(currentTarget).addClass('active'); + this.$('.task-tabs').find('li').removeClass('active'); + this.$(currentTarget).addClass('active'); this.model.changeView(datatype); } }); Views.DataSection = FauxtonAPI.View.extend({ showData: function(){ - var that = this, - currentData = this.model.getCurrentViewData(); - //remove the old stuff in a nice clean way + var currentData = this.model.getCurrentViewData(); + if (this.dataView) { - this.dataView.remove(); + this.dataView.update(currentData, this.model.get('currentView').replace('_',' ')); + } else { + this.dataView = this.insertView( new Views.TableData({ + collection: currentData, + currentView: this.model.get('currentView').replace('_',' ') + })); } - - //add the new stuff - this.dataView = that.insertView( new Views.TableData({ - collection: currentData, - currentView: this.model.get('currentView').replace('_',' ') - })); - }, showDataAndRender: function () { this.showData(); - this.render(); + this.dataView.render(); }, beforeRender: function () { @@ -133,6 +130,12 @@ function (app, FauxtonAPI, activetasks) { collection: this.collection }; }, + + update: function (collection, currentView) { + this.collection = collection; + this.currentView = currentView; + }, + beforeRender: function(){ //iterate over the collection to add each this.collection.forEach(function(item) { diff --git a/src/fauxton/test/core/layoutSpec.js b/src/fauxton/test/core/layoutSpec.js new file mode 100644 index 000000000..3876b701a --- /dev/null +++ b/src/fauxton/test/core/layoutSpec.js @@ -0,0 +1,94 @@ +// Licensed 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. +define([ + 'modules/fauxton/layout', + 'testUtils' +], function (Layout, testUtils) { + var assert = testUtils.assert; + + describe("Faxuton Layout", function () { + var layout; + + beforeEach(function () { + var navBar = new Backbone.View(); + var apiBar = new Backbone.View(); + layout = new Layout(navBar, apiBar); + }); + + describe('#setTemplate', function () { + + it("Should set template without prefix", function () { + layout.setTemplate('myTemplate'); + + assert.equal(layout.layout.template, 'templates/layouts/myTemplate'); + + }); + + it("Should set template with prefix", function () { + layout.setTemplate({name: 'myTemplate', prefix: 'myPrefix/'}); + + assert.equal(layout.layout.template, 'myPrefix/myTemplate'); + }); + + it("Should remove old views", function () { + var view = { + remove: function () {} + }; + + layout.layoutViews = { + 'selector': view + }; + + var mockRemove = sinon.spy(view, 'remove'); + layout.setTemplate('myTemplate'); + assert.ok(mockRemove.calledOnce); + + }); + + it("Should render", function () { + var mockRender = sinon.spy(layout, 'render'); + + layout.setTemplate('myTemplate'); + + assert.ok(mockRender.calledOnce); + + }); + + }); + + describe('#renderView', function () { + + it('Should render existing view', function () { + var view = new Backbone.View(); + var mockRender = sinon.spy(view, 'render'); + layout.layoutViews = { + '#selector': view + }; + + var out = layout.renderView('#selector'); + + assert.ok(mockRender.calledOnce); + }); + + it('Should return false for non-existing view', function () { + var view = new Backbone.View(); + layout.layoutViews = { + 'selector': view + }; + + var out = layout.renderView('wrongSelector'); + assert.notOk(out, 'No view found'); + }); + }); + + }); +}); diff --git a/src/fauxton/test/mocha/testUtils.js b/src/fauxton/test/mocha/testUtils.js index 08b46de61..3eb111830 100644 --- a/src/fauxton/test/mocha/testUtils.js +++ b/src/fauxton/test/mocha/testUtils.js @@ -13,13 +13,38 @@ define([ "chai", "sinon-chai", + "underscore" ], function(chai, sinonChai) { chai.use(sinonChai); + var ViewSandbox = function () { + this.initialize(); + }; + + _.extend(ViewSandbox.prototype, { + initialize: function () { + this.$el = $('<div></div>'); + this.$ = this.$el.find; + }, + views: [], + renderView: function (view) { + this.views.push(view); + this.$el.append(view.el); + view.render(); + }, + + remove: function () { + _.each(this.views, function (view) { + view.remove(); + }, this); + } + }); + return { chai: chai, - assert: chai.assert + assert: chai.assert, + ViewSandbox: ViewSandbox }; }); diff --git a/src/fauxton/test/runner.html b/src/fauxton/test/runner.html index b86855ec7..b27fdda66 100644 --- a/src/fauxton/test/runner.html +++ b/src/fauxton/test/runner.html @@ -11,6 +11,7 @@ <script type="text/javascript"> // MOCHA SETUP mocha.setup('bdd'); + mocha.reporter('html'); </script> <script data-main="./test.config.js" src="../assets/js/libs/require.js"></script> </body> |