diff --git a/zeppelin-web/.jshintrc b/zeppelin-web/.jshintrc index 374aab426f9..bb2795019e8 100644 --- a/zeppelin-web/.jshintrc +++ b/zeppelin-web/.jshintrc @@ -19,6 +19,8 @@ "strict": true, "trailing": true, "smarttabs": true, + "jasmine": true, + "predef": [ "inject" ], "globals": { "angular": false, "_": false, diff --git a/zeppelin-web/src/app/notebook/notebook.controller.js b/zeppelin-web/src/app/notebook/notebook.controller.js index 11a558f8aab..d5f30241d5e 100644 --- a/zeppelin-web/src/app/notebook/notebook.controller.js +++ b/zeppelin-web/src/app/notebook/notebook.controller.js @@ -21,6 +21,7 @@ angular.module('zeppelinWebApp').controller('NotebookCtrl', function($scope, $ro $scope.editorToggled = false; $scope.tableToggled = false; $scope.viewOnly = false; + $scope.showSetting = false; $scope.looknfeelOption = [ 'default', 'simple', 'report']; $scope.cronOption = [ {name: 'None', value : undefined}, diff --git a/zeppelin-web/test/spec/controllers/main.js b/zeppelin-web/test/spec/controllers/main.js index 3b2e9da82c2..16785a9004b 100644 --- a/zeppelin-web/test/spec/controllers/main.js +++ b/zeppelin-web/test/spec/controllers/main.js @@ -1,23 +1,32 @@ 'use strict'; -describe('Controller: MainCtrl', function () { - - // load the controller's module +describe('Controller: MainCtrl', function() { beforeEach(module('zeppelinWebApp')); - var MainCtrl, - scope; + var MainCtrl; + var scope; + var rootScope; - // Initialize the controller and a mock scope - beforeEach(inject(function ($controller, $rootScope) { + beforeEach(inject(function($controller, $rootScope) { + rootScope = $rootScope; scope = $rootScope.$new(); MainCtrl = $controller('MainCtrl', { $scope: scope }); })); - it('should attach a asIframe to the scope', function () { + it('should attach a asIframe to the scope and the default value should be false', function() { expect(scope.asIframe).toBeDefined(); + expect(scope.asIframe).toEqual(false); + }); + + it('should set the default value of "looknfeel to "default"', function() { + expect(scope.looknfeel).toEqual('default'); + }); + + it('should set asIframe flag to true when a controller broadcasts setIframe event', function() { + rootScope.$broadcast('setIframe', true); + expect(scope.asIframe).toEqual(true); }); }); diff --git a/zeppelin-web/test/spec/controllers/notebook.js b/zeppelin-web/test/spec/controllers/notebook.js index 5dde4e2cf06..313aa9d2e30 100644 --- a/zeppelin-web/test/spec/controllers/notebook.js +++ b/zeppelin-web/test/spec/controllers/notebook.js @@ -1,20 +1,103 @@ 'use strict'; describe('Controller: NotebookCtrl', function() { - - // load the controller's module beforeEach(module('zeppelinWebApp')); - var NotebookCtrl, scope; + var NotebookCtrl; + var scope; + + var websocketMsgSrvMock = { + getNotebook: function() {} + }; + + var baseUrlSrvMock = { + getRestApiBase: function() { + return 'http://localhost:8080'; + } + }; + + var noteMock = { + id: 1, + name: 'my notebook', + config: {}, + }; - // Initialize the controller and a mock scope - beforeEach(inject(function($controller, $rootScope/*, websocketMsgSrv, baseUrlSrv*/) { + beforeEach(inject(function($controller, $rootScope) { scope = $rootScope.$new(); NotebookCtrl = $controller('NotebookCtrl', { - $scope: scope + $scope: scope, + websocketMsgSrv: websocketMsgSrvMock, + baseUrlSrv: baseUrlSrvMock }); })); - //Test Can be writting for to test NotebookCtrl + beforeEach(function() { + scope.note = noteMock; + }); + + var functions = ['getCronOptionNameFromValue', 'removeNote', 'runNote', 'saveNote', 'toggleAllEditor', + 'showAllEditor', 'hideAllEditor', 'toggleAllTable', 'hideAllTable', 'showAllTable', 'isNoteRunning', + 'killSaveTimer', 'startSaveTimer', 'setLookAndFeel', 'setCronScheduler', 'setConfig', 'sendNewName', + 'openSetting', 'closeSetting', 'saveSetting', 'toggleSetting']; + + functions.forEach(function(fn) { + it('check for scope functions to be defined : ' + fn, function() { + expect(scope[fn]).toBeDefined(); + }); + }); + + it('should set default value of "showEditor" to false', function() { + expect(scope.showEditor).toEqual(false); + }); + + it('should set default value of "editorToggled" to false', function() { + expect(scope.editorToggled).toEqual(false); + }); + + it('should set showSetting to true when openSetting is called', function() { + scope.openSetting(); + expect(scope.showSetting).toEqual(true); + }); + + it('should set showSetting to false when closeSetting is called', function() { + scope.closeSetting(); + expect(scope.showSetting).toEqual(false); + }); + + it('should return the correct value for getCronOptionNameFromValue', function() { + var none = scope.getCronOptionNameFromValue(); + var oneMin = scope.getCronOptionNameFromValue('0 0/1 * * * ?'); + var fiveMin = scope.getCronOptionNameFromValue('0 0/5 * * * ?'); + var oneHour = scope.getCronOptionNameFromValue('0 0 0/1 * * ?'); + var threeHours = scope.getCronOptionNameFromValue('0 0 0/3 * * ?'); + var sixHours = scope.getCronOptionNameFromValue('0 0 0/6 * * ?'); + var twelveHours = scope.getCronOptionNameFromValue('0 0 0/12 * * ?'); + var oneDay = scope.getCronOptionNameFromValue('0 0 0 * * ?'); + + expect(none).toEqual(''); + expect(oneMin).toEqual('1m'); + expect(fiveMin).toEqual('5m'); + expect(oneHour).toEqual('1h'); + expect(threeHours).toEqual('3h'); + expect(sixHours).toEqual('6h'); + expect(twelveHours).toEqual('12h'); + expect(oneDay).toEqual('1d'); + }); + + it('default value for isNoteDirty should be null', function() { + expect(scope.isNoteDirty).toEqual(null); + }); + + it('calling startSaveTimer should first call killSaveTimer and start a new timer', function() { + expect(scope.saveTimer).toEqual(null); + scope.startSaveTimer(); + expect(scope.isNoteDirty).toEqual(true); + expect(scope.saveTimer).toBeTruthy(); + }); + + it('calling killSaveTimer should clear saveTimer flag', function() { + scope.killSaveTimer(); + expect(scope.saveTimer).toEqual(null); + }); }); diff --git a/zeppelin-web/test/spec/controllers/paragraph.js b/zeppelin-web/test/spec/controllers/paragraph.js index 1ea4d264b0e..abde0d91864 100644 --- a/zeppelin-web/test/spec/controllers/paragraph.js +++ b/zeppelin-web/test/spec/controllers/paragraph.js @@ -1,19 +1,82 @@ 'use strict'; -describe('Controller: ParagraphCtrl', function () { +describe('Controller: ParagraphCtrl', function() { - // load the controller's module beforeEach(module('zeppelinWebApp')); - var ParagraphCtrl, scope; + var ParagraphCtrl; + var scope; + var websocketMsgSrvMock = {}; + var paragraphMock = { + config: {} + }; - // Initialize the controller and a mock scope - beforeEach(inject(function ($controller, $rootScope) { + beforeEach(inject(function($controller, $rootScope) { scope = $rootScope.$new(); ParagraphCtrl = $controller('ParagraphCtrl', { - $scope: scope + $scope: scope, + websocketMsgSrv: websocketMsgSrvMock, + $element: {} }); + scope.init(paragraphMock); })); - //Write test to test ParagraphCtrl + var functions = ['isRunning', 'getIframeDimensions', 'cancelParagraph', 'runParagraph', 'saveParagraph', + 'moveUp', 'moveDown', 'insertNew', 'removeParagraph', 'toggleEditor', 'closeEditor', 'openEditor', + 'closeTable', 'openTable', 'showTitle', 'hideTitle', 'setTitle', 'showLineNumbers', 'hideLineNumbers', + 'changeColWidth', 'columnWidthClass', 'toggleGraphOption', 'toggleOutput', 'loadForm', + 'aceChanged', 'aceLoaded', 'getEditorValue', 'getProgress', 'getExecutionTime', 'isResultOutdated', + 'getResultType', 'loadTableData', 'setGraphMode', 'isGraphMode', 'onGraphOptionChange', + 'removeGraphOptionKeys', 'removeGraphOptionValues', 'removeGraphOptionGroups', 'setGraphOptionValueAggr', + 'removeScatterOptionXaxis', 'removeScatterOptionYaxis', 'removeScatterOptionGroup', + 'removeScatterOptionSize']; + + functions.forEach(function(fn) { + it('check for scope functions to be defined : ' + fn, function() { + expect(scope[fn]).toBeDefined(); + }); + }); + + it('getResultType should return "TEXT" when the type is unknown', function() { + expect(scope.getResultType()).toEqual('TEXT'); + }); + + it('init value for colWidthOption should be false', function() { + expect(scope.colWidthOption).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]); + }); + + it('init value for paragraphFocused should be false', function() { + expect(scope.paragraphFocused).toEqual(false); + }); + + it('loadTableData should be called when the result type is "TABLE" and the Graph mode should be "table"', function() { + scope.getResultType = jasmine.createSpy('getResultType spy').andCallFake(function() { + return 'TABLE'; + }); + spyOn(scope, 'loadTableData'); + spyOn(scope, 'setGraphMode'); + scope.init(paragraphMock); + expect(scope.loadTableData).toHaveBeenCalled(); + expect(scope.setGraphMode).toHaveBeenCalled(); + expect(scope.getGraphMode()).toEqual('table'); + }); + + it('renderHtml should be called when the result type is "HTML"', function() { + scope.getResultType = jasmine.createSpy('getResultType spy').andCallFake(function() { + return 'HTML'; + }); + spyOn(scope, 'renderHtml'); + scope.init(paragraphMock); + expect(scope.renderHtml).toHaveBeenCalled(); + }); + + it('renderAngular should be called when the result type is "ANGULAR"', function() { + scope.getResultType = jasmine.createSpy('getResultType spy').andCallFake(function() { + return 'ANGULAR'; + }); + spyOn(scope, 'renderAngular'); + scope.init(paragraphMock); + expect(scope.renderAngular).toHaveBeenCalled(); + }); + });