aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStas Vilchik <vilchiks@gmail.com>2014-07-11 12:42:14 +0600
committerStas Vilchik <vilchiks@gmail.com>2014-07-15 12:04:08 +0600
commit557db7be44ec049f777c7705eace34f2486a93c6 (patch)
tree4fcb3625dbc47c1b806cbbdefaad74c1e3488fd4
parentfb1f98a971cff6313798b3e00188c109a7c91f5e (diff)
downloadsonarqube-557db7be44ec049f777c7705eace34f2486a93c6.tar.gz
sonarqube-557db7be44ec049f777c7705eace34f2486a93c6.zip
karma tests
-rw-r--r--server/sonar-web/Gruntfile.coffee10
-rw-r--r--server/sonar-web/src/main/js/translate.js2
-rw-r--r--sonar-server/karma.conf.js130
-rw-r--r--sonar-server/src/main/coffee/tests/common/inputsSpec.coffee87
-rw-r--r--sonar-server/src/main/coffee/tests/component-viewer/baseSpec.coffee30
-rw-r--r--sonar-server/src/main/coffee/tests/translateSpec.coffee75
-rw-r--r--sonar-server/src/main/coffee/tests/widgets/BaseSpec.coffee47
-rw-r--r--sonar-server/src/main/coffee/tests/widgets/treemapSpec.coffee49
-rw-r--r--sonar-server/src/main/js/tests/main.js44
-rw-r--r--sonar-server/src/main/js/tests/navigator/filters/BaseFilterViewSpec.js15
-rw-r--r--sonar-server/src/main/js/tests/navigator/filters/ChoiceFilterViewSpec.js39
11 files changed, 525 insertions, 3 deletions
diff --git a/server/sonar-web/Gruntfile.coffee b/server/sonar-web/Gruntfile.coffee
index 244db1952ad..ae6102b43f2 100644
--- a/server/sonar-web/Gruntfile.coffee
+++ b/server/sonar-web/Gruntfile.coffee
@@ -253,6 +253,12 @@ module.exports = (grunt) ->
src: '<%= pkg.sources %>js/require.js', dest: '<%= pkg.assets %>js/require.js'
+ karma:
+ unit:
+ configFile: 'karma.conf.js'
+ singleRun: true
+
+
express:
dev:
options:
@@ -264,7 +270,7 @@ module.exports = (grunt) ->
options:
test: true
'no-colors': true
- src: ['<%= pkg.sources %>js/tests/**/*-spec.js']
+ src: ['<%= pkg.sources %>js/tests/e2e/tests/**/*.js']
watch:
@@ -315,4 +321,4 @@ module.exports = (grunt) ->
'concat:build',
'requirejs', 'clean:js', 'copy:build', 'copy:requirejs', 'clean:build']
- grunt.registerTask 'test', ['coffee:build', 'handlebars:build', 'copy:js', 'concat:dev', 'express', 'casper']
+ grunt.registerTask 'test', ['coffee:build', 'handlebars:build', 'copy:js', 'concat:dev', 'karma:unit']
diff --git a/server/sonar-web/src/main/js/translate.js b/server/sonar-web/src/main/js/translate.js
index c86d28c09ef..e6fd9b2f16a 100644
--- a/server/sonar-web/src/main/js/translate.js
+++ b/server/sonar-web/src/main/js/translate.js
@@ -94,7 +94,7 @@
window.messages = bundle;
localStorage.setItem('l10n.bundle', JSON.stringify(bundle));
- } else if (jqXHR.status == 304) {
+ } else if (jqXHR.status === 304) {
window.messages = JSON.parse(localStorage.getItem('l10n.bundle'));
}
});
diff --git a/sonar-server/karma.conf.js b/sonar-server/karma.conf.js
new file mode 100644
index 00000000000..a247efa23e1
--- /dev/null
+++ b/sonar-server/karma.conf.js
@@ -0,0 +1,130 @@
+/* global module:false, karma:false */
+
+// Karma configuration for JS application
+
+// GLOBAL INSTALLATION
+// sonar-server$ npm install -g
+// sonar-server$ karma start
+
+// LOCAL INSTALLATION
+// sonar-server$ npm install
+// sonar-server$ ./node_modules/.bin/karma start
+
+module.exports = function(config) {
+ config.set({
+
+ // base path, that will be used to resolve files and exclude
+ basePath: 'src/main/webapp/js',
+
+
+ // frameworks to use
+ frameworks: ['jasmine'],
+
+
+ // list of files / patterns to load in the browser
+ files: [
+ // dependencies
+ 'sonar.js',
+ 'require.js',
+
+ // libs
+ { pattern: 'third-party/backbone.js', included: false },
+ { pattern: 'third-party/backbone.marionette.js', included: false },
+ { pattern: 'third-party/handlebars.js', included: false },
+ { pattern: 'third-party/moment.js', included: false },
+ { pattern: 'third-party/jquery.mockjax.js', included: false },
+
+ // common
+ { pattern: 'common/**/*.js', included: false },
+
+ // app
+ { pattern: 'navigator/**/*.js', included: false },
+ { pattern: 'quality-gate/**/*.js', included: false },
+ { pattern: 'issues/**/*.js', included: false },
+ { pattern: 'component-viewer/**/*.js', included: false },
+ { pattern: 'templates/**/*.js', included: false },
+
+ // tests
+ { pattern: 'tests/**/*Spec.js', included: false },
+
+ 'tests/main.js'
+ ],
+
+
+ // list of files to exclude
+ exclude: [
+
+ ],
+
+
+ preprocessors: {
+ 'navigator/**/*.js': 'coverage',
+ 'component-viewer/**/*.js': 'coverage',
+ 'common/inputs.js': 'coverage',
+ 'translate.js': 'coverage'
+ },
+
+
+ plugins: [
+ 'karma-jasmine',
+ 'karma-phantomjs-launcher',
+ 'karma-coverage',
+ 'karma-junit-reporter'
+ ],
+
+
+ // test results reporter to use
+ reporters: ['progress', 'coverage', 'junit'],
+
+
+ coverageReporter: {
+ type : 'lcovonly',
+ dir : '../../../../target/karma/coverage/'
+ },
+
+ junitReporter: {
+ outputFile : '../../../../target/karma/test-results.xml'
+ },
+
+ // WARNING - the 2 following ports should not be hardcoded in CI environments
+ // web server port
+ port: 9876,
+
+
+ // cli runner port
+ runnerPort: 9100,
+
+
+ // enable / disable colors in the output (reporters and logs)
+ colors: true,
+
+
+ // level of logging
+ // possible values: karma.LOG_DISABLE || karma.LOG_ERROR || karma.LOG_WARN || karma.LOG_INFO || karma.LOG_DEBUG
+ logLevel: config.LOG_WARN,
+
+
+ // enable / disable watching file and executing tests whenever any file changes
+ autoWatch: false,
+
+
+ // Start these browsers, currently available:
+ // - Chrome
+ // - ChromeCanary
+ // - Firefox
+ // - Opera
+ // - Safari (only Mac)
+ // - PhantomJS
+ // - IE (only Windows)
+ browsers: ['PhantomJS'],
+
+
+ // If browser does not capture in given timeout [ms], kill it
+ captureTimeout: 60000,
+
+
+ // Continuous Integration mode
+ // if true, it capture browsers, run tests and exit
+ singleRun: false
+ });
+};
diff --git a/sonar-server/src/main/coffee/tests/common/inputsSpec.coffee b/sonar-server/src/main/coffee/tests/common/inputsSpec.coffee
new file mode 100644
index 00000000000..3cbc6591925
--- /dev/null
+++ b/sonar-server/src/main/coffee/tests/common/inputsSpec.coffee
@@ -0,0 +1,87 @@
+$ = jQuery
+
+describe 'WORK_DUR suite', ->
+
+ beforeEach ->
+ window.SS = {}
+ window.SS.phrases =
+ 'work_duration':
+ 'x_days': '{0}d', 'x_hours': '{0}h', 'x_minutes': '{0}min'
+
+ @input = $('<input type="text">')
+ @input.appendTo $('body')
+ @input.data 'type', 'WORK_DUR'
+
+
+ it 'converts', ->
+ @input.originalVal '2d 7h 13min'
+ expect(@input.val()).toBe 1393
+
+ it 'converts only days', ->
+ @input.originalVal '1d'
+ expect(@input.val()).toBe 480
+
+ it 'converts hours with minutes', ->
+ @input.originalVal '2h 30min'
+ expect(@input.val()).toBe 150
+
+ it 'converts zero', ->
+ @input.originalVal '0'
+ expect(@input.val()).toBe 0
+
+
+ it 'restores', ->
+ @input.val 1393
+ expect(@input.originalVal()).toBe '2d 7h 13min'
+
+ it 'restores zero', ->
+ @input.val '0'
+ expect(@input.originalVal()).toBe '0'
+
+
+ it 'returns initially incorrect value', ->
+ @input.val 'something'
+ expect(@input.val()).toBe 'something'
+
+
+describe 'RATING suite', ->
+
+ beforeEach ->
+ @input = $('<input type="text">')
+ @input.appendTo $('body')
+ @input.data 'type', 'RATING'
+
+
+ it 'converts A', ->
+ @input.originalVal 'A'
+ expect(@input.val()).toBe 1
+
+
+ it 'converts B', ->
+ @input.originalVal 'B'
+ expect(@input.val()).toBe 2
+
+
+ it 'converts E', ->
+ @input.originalVal 'E'
+ expect(@input.val()).toBe 5
+
+
+ it 'does not convert F', ->
+ @input.originalVal 'F'
+ expect(@input.val()).toBe 'F'
+
+
+ it 'restores A', ->
+ @input.val 1
+ expect(@input.originalVal()).toBe 'A'
+
+
+ it 'restores E', ->
+ @input.val 5
+ expect(@input.originalVal()).toBe 'E'
+
+
+ it 'returns initially incorrect value', ->
+ @input.val 'something'
+ expect(@input.val()).toBe 'something'
diff --git a/sonar-server/src/main/coffee/tests/component-viewer/baseSpec.coffee b/sonar-server/src/main/coffee/tests/component-viewer/baseSpec.coffee
new file mode 100644
index 00000000000..7fd5a4cbe50
--- /dev/null
+++ b/sonar-server/src/main/coffee/tests/component-viewer/baseSpec.coffee
@@ -0,0 +1,30 @@
+$ = jQuery
+window.baseUrl = ''
+window.suppressTranslationWarnings = true
+
+
+define [
+ 'component-viewer/main'
+], (
+ ComponentViewer
+) ->
+
+ describe 'Component Viewer Base Test Suite', ->
+
+ beforeEach ->
+ @viewer = new ComponentViewer()
+ @viewer.render().$el.appendTo $('body')
+
+
+ afterEach ->
+ @viewer.close()
+
+
+ it 'attaches to the page', ->
+ expect($('.component-viewer', 'body').length).toBe 1
+
+
+ it 'has all parts', ->
+ expect(@viewer.$('.component-viewer-header').length).toBe 1
+ expect(@viewer.$('.component-viewer-source').length).toBe 1
+ expect(@viewer.$('.component-viewer-workspace').length).toBe 1
diff --git a/sonar-server/src/main/coffee/tests/translateSpec.coffee b/sonar-server/src/main/coffee/tests/translateSpec.coffee
new file mode 100644
index 00000000000..7b4576bcfff
--- /dev/null
+++ b/sonar-server/src/main/coffee/tests/translateSpec.coffee
@@ -0,0 +1,75 @@
+$ = jQuery
+
+describe 'translation "t" suite', ->
+
+ beforeEach ->
+ window.messages =
+ 'something': 'SOMETHING'
+ 'something_with_underscore': 'SOMETHING_WITH_UNDERSCORE'
+ 'something_with{braces}': 'SOMETHING_WITH{braces}'
+
+ window.SS =
+ phrases:
+ 'something': 'SOMETHING ANOTHER'
+
+
+ afterEach ->
+ window.messages = window.SS = undefined
+
+
+ it 'translates', ->
+ expect(t('something')).toBe 'SOMETHING'
+
+
+ it 'translates with underscore', ->
+ expect(t('something_with_underscore')).toBe 'SOMETHING_WITH_UNDERSCORE'
+
+
+ it 'translates with braces', ->
+ expect(t('something_with{braces}')).toBe 'SOMETHING_WITH{braces}'
+
+
+ it 'fallbacks to "translate"', ->
+ window.messages = undefined
+ expect(t('something')).toBe 'SOMETHING ANOTHER'
+
+
+ it 'returns the key when no translation', ->
+ expect(t('something_another')).toBe 'something_another'
+
+
+
+describe 'translation "translate" suite', ->
+
+ beforeEach ->
+ window.SS =
+ phrases:
+ 'something': 'SOMETHING'
+ 'something_with_underscore': 'SOMETHING_WITH_UNDERSCORE'
+ 'something_with{braces}': 'SOMETHING_WITH{braces}'
+
+
+ afterEach ->
+ window.messages = window.SS = undefined
+
+
+ it 'translates', ->
+ expect(translate('something')).toBe 'SOMETHING'
+
+
+ it 'translates with underscore', ->
+ expect(translate('something_with_underscore')).toBe 'SOMETHING_WITH_UNDERSCORE'
+
+
+ it 'translates with braces', ->
+ expect(translate('something_with{braces}')).toBe 'SOMETHING_WITH{braces}'
+
+
+ it 'returns the key when no translation', ->
+ expect(translate('something_another')).toBe 'something_another'
+
+
+ it 'does not fail when there is no dictionary', ->
+ window.SS = undefined
+ expect(translate('something_another')).toBe 'something_another'
+
diff --git a/sonar-server/src/main/coffee/tests/widgets/BaseSpec.coffee b/sonar-server/src/main/coffee/tests/widgets/BaseSpec.coffee
new file mode 100644
index 00000000000..b869aed84d5
--- /dev/null
+++ b/sonar-server/src/main/coffee/tests/widgets/BaseSpec.coffee
@@ -0,0 +1,47 @@
+$ = jQuery
+
+describe 'base widget suite', ->
+
+ it 'exists', ->
+ expect(window.SonarWidgets).toBeDefined()
+ expect(window.SonarWidgets.BaseWidget).toBeDefined()
+
+
+ it 'adds fields', ->
+ widget = new window.SonarWidgets.BaseWidget()
+ widget.addField 'fieldName', 1
+
+ expect(typeof widget.fieldName).toBe 'function'
+ expect(widget.fieldName()).toBe 1
+
+ expect(widget.fieldName(2)).toBe widget
+ expect(widget.fieldName()).toBe 2
+
+
+ it 'adds metrics', ->
+ widget = new window.SonarWidgets.BaseWidget()
+ widget.addField 'metrics', 'metricA': { name: 'Metric A', someField: 2 }
+ widget.addField 'metricsPriority', ['metricA']
+ widget.addMetric 'myMetric', 0
+
+ expect(widget.myMetric).toBeDefined()
+ expect(widget.myMetric.key).toBe 'metricA'
+ expect(widget.myMetric.name).toBe 'Metric A'
+ expect(widget.myMetric.someField).toBe 2
+ expect(typeof widget.myMetric.value).toBe 'function'
+ expect(typeof widget.myMetric.formattedValue).toBe 'function'
+
+
+ it 'has default properties', ->
+ widget = new window.SonarWidgets.BaseWidget()
+
+ expect(widget.components).toBeDefined()
+ expect(widget.metrics).toBeDefined()
+ expect(widget.metricsPriority).toBeDefined()
+ expect(widget.options).toBeDefined()
+
+
+ it 'created "translate" string', ->
+ widget = new window.SonarWidgets.BaseWidget()
+
+ expect(widget.trans(1, 2)).toBe 'translate(1,2)'
diff --git a/sonar-server/src/main/coffee/tests/widgets/treemapSpec.coffee b/sonar-server/src/main/coffee/tests/widgets/treemapSpec.coffee
new file mode 100644
index 00000000000..4f1ddcfd20a
--- /dev/null
+++ b/sonar-server/src/main/coffee/tests/widgets/treemapSpec.coffee
@@ -0,0 +1,49 @@
+$ = jQuery
+
+METRICS =
+ ncloc:
+ name: 'Lines of code'
+ coverage:
+ name: 'Coverage'
+ direction: -1
+
+METRICS_PRIORITY = ['coverage', 'ncloc']
+
+COMPONENTS = [
+ { key: 'some-key-1', name: 'Some Name 1', longName: 'Some Long Name 1', qualifier: 'TRK', measures }
+]
+
+
+
+describe 'treemap widget suite', ->
+
+ uid = 1
+
+ render = (treemap, components = COMPONENTS, metrics = METRICS, metricsPriority = METRICS_PRIORITY) ->
+ elementId = 'treemap-' + ++uid
+ $("<div id='#{elementId}'></div>").appendTo 'body'
+ treemap.metrics(metrics).metricsPriority(metricsPriority).components(components).options(
+ heightInPercents: 55
+ maxItems: 10
+ maxItemsReachedMessage: ''
+ baseUrl: ''
+ noData: ''
+ ).render('#' + elementId);
+
+
+ close = ->
+ elementId = 'treemap-' + uid
+ $('#' + elementId).delete()
+
+
+ beforeEach ->
+ @treemap = new window.SonarWidgets.Treemap()
+
+
+ afterEach ->
+ @treemap = undefined
+ close()
+
+
+ it 'renders', ->
+ render @treemap
diff --git a/sonar-server/src/main/js/tests/main.js b/sonar-server/src/main/js/tests/main.js
new file mode 100644
index 00000000000..eb95545cb5b
--- /dev/null
+++ b/sonar-server/src/main/js/tests/main.js
@@ -0,0 +1,44 @@
+window.__karma__.loaded = function() {};
+
+var tests = [];
+for (var file in window.__karma__.files) {
+ if (window.__karma__.files.hasOwnProperty(file)) {
+ if (/Spec\.js$/.test(file)) {
+ tests.push(file);
+ }
+ }
+}
+
+requirejs.config({
+ baseUrl: '/base',
+
+ paths: {
+ 'backbone': 'third-party/backbone',
+ 'backbone.marionette': 'third-party/backbone.marionette',
+ 'handlebars': 'third-party/handlebars',
+ 'moment': 'third-party/moment'
+ },
+
+ shim: {
+ 'backbone.marionette': {
+ deps: ['backbone'],
+ exports: 'Marionette'
+ },
+ 'backbone': {
+ exports: 'Backbone'
+ },
+ 'handlebars': {
+ exports: 'Handlebars'
+ },
+ 'moment': {
+ exports: 'moment'
+ }
+ },
+
+ // ask Require.js to load these files (all our tests)
+ deps: tests,
+
+ // start test run, once Require.js is done
+ callback: window.__karma__.start
+
+});
diff --git a/sonar-server/src/main/js/tests/navigator/filters/BaseFilterViewSpec.js b/sonar-server/src/main/js/tests/navigator/filters/BaseFilterViewSpec.js
new file mode 100644
index 00000000000..b1a0ab15c4f
--- /dev/null
+++ b/sonar-server/src/main/js/tests/navigator/filters/BaseFilterViewSpec.js
@@ -0,0 +1,15 @@
+define(['navigator/filters/base-filters'], function(BaseFilters) {
+
+ describe('BaseFilterView', function() {
+
+ it('initializes', function() {
+ var baseFilterView = new BaseFilters.BaseFilterView({
+ model: new BaseFilters.Filter()
+ });
+ expect(baseFilterView.detailsView).toBeDefined();
+ expect(baseFilterView.detailsView.options.filterView).toBe(baseFilterView);
+ });
+
+ });
+
+});
diff --git a/sonar-server/src/main/js/tests/navigator/filters/ChoiceFilterViewSpec.js b/sonar-server/src/main/js/tests/navigator/filters/ChoiceFilterViewSpec.js
new file mode 100644
index 00000000000..3b905a9f88f
--- /dev/null
+++ b/sonar-server/src/main/js/tests/navigator/filters/ChoiceFilterViewSpec.js
@@ -0,0 +1,39 @@
+define(['navigator/filters/base-filters', 'navigator/filters/choice-filters'], function(BaseFilters, ChoiceFilters) {
+
+ describe('BaseFilterView', function() {
+ var choices, choiceFilter, choiceFilterView;
+
+ beforeEach(function() {
+ choices = {
+ 'ONE': 'one',
+ 'TWO': 'two',
+ 'THREE': 'three',
+ '!OPPOSITE': 'opposite'
+ };
+
+ choiceFilter = new BaseFilters.Filter({
+ name: 'Choice Filter Name',
+ property: 'choiceFilterProperty',
+ type: ChoiceFilters.ChoiceFilterView,
+ enabled: true,
+ optional: false,
+ choices: choices
+ });
+
+ choiceFilterView = new ChoiceFilters.ChoiceFilterView({
+ model: choiceFilter
+ });
+ });
+
+ it('creates choices', function() {
+ expect(choiceFilterView.choices).toBeDefined();
+ expect(choiceFilterView.choices.length).toBe(Object.keys(choices).length);
+ });
+
+ it('does not have selected by default', function() {
+ expect(choiceFilterView.getSelected().length).toBe(0);
+ });
+
+ });
+
+});