Skip to content

Commit c322455

Browse files
committed
chore: Add Gruntfile, update Karma configuration & fix JSHint errors
Leveraging Grunt to check for style issues and run the Karma tests makes it easier to run those processes. The Gruntfile in use here is based on that of ui-utils, and the Karma config file (which has been renamed Karma.conf.js for consistency with other projects) has been re-generated with karma init.
1 parent 487f35a commit c322455

File tree

8 files changed

+215
-80
lines changed

8 files changed

+215
-80
lines changed

.jshintrc

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"curly": true,
3+
"eqeqeq": true,
4+
"immed": true,
5+
"latedef": true,
6+
"newcap": true,
7+
"noarg": true,
8+
"sub": true,
9+
"boss": true,
10+
"eqnull": true
11+
}

Gruntfile.js

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
module.exports = function (grunt) {
2+
'use strict';
3+
4+
var initConfig;
5+
6+
// Loading external tasks
7+
grunt.loadNpmTasks('grunt-contrib-jshint');
8+
grunt.loadNpmTasks('grunt-contrib-watch');
9+
grunt.loadNpmTasks('grunt-karma');
10+
11+
// Project configuration.
12+
initConfig = {
13+
bower: 'bower_components',
14+
pkg: grunt.file.readJSON('package.json'),
15+
watch: {
16+
// Lint & run unit tests in Karma
17+
// Just running `$ grunt watch` will only lint your code; to run tests
18+
// on watch, use `$ grunt watch:karma` to start a Karma server first
19+
files: ['src/select2.js', 'test/select2Spec.js'],
20+
tasks: ['jshint', 'karma:headless:run']
21+
},
22+
karma: {
23+
options: {
24+
configFile: 'test/karma.conf.js'
25+
},
26+
unit: {
27+
singleRun: true,
28+
browsers: ['Firefox', 'PhantomJS']
29+
},
30+
headless: {
31+
singleRun: true,
32+
browsers: ['PhantomJS']
33+
},
34+
server: {
35+
background: true,
36+
browsers: ['Firefox', 'PhantomJS']
37+
}
38+
},
39+
jshint: {
40+
all:[
41+
'gruntFile.js',
42+
'src/**/*.js',
43+
'test/**/*Spec.js'
44+
],
45+
options: {
46+
jshintrc: '.jshintrc'
47+
}
48+
},
49+
};
50+
51+
// Register tasks
52+
grunt.registerTask('default', ['jshint', 'karma:unit']);
53+
grunt.registerTask('watch:karma', ['karma:server', 'watch']);
54+
55+
grunt.initConfig(initConfig);
56+
};

README.md

+23-21
Original file line numberDiff line numberDiff line change
@@ -10,40 +10,42 @@ This directive allows you to enhance your select elements with behaviour from th
1010

1111
## Setup
1212

13-
1. Install **karma**
14-
`$ npm install -g karma`
15-
2. Install **bower**
16-
`$ npm install -g bower`
17-
4. Install components
13+
1. Install **Karma**, **Grunt** and **Bower**
14+
`$ npm install -g karma grunt-cli bower`
15+
2. Install development dependencies
16+
`$ npm install`
17+
3. Install components
1818
`$ bower install`
1919
4. ???
2020
5. Profit!
2121

2222
## Testing
2323

24-
`$ karma start test/test.conf.js --browsers=Chrome`
24+
We use [Grunt](http://gruntjs.com/) to check for JavaScript syntax errors and execute all unit tests. To run grunt, simply execute:
2525

26-
# Usage
26+
`$ grunt`
2727

28-
We use [bower](https://github.com/bower/bower) for dependency management. Add
28+
To have Grunt automatically lint and test your files whenever you make a code change, use:
2929

30-
```javascript
31-
dependencies: {
32-
"angular-ui-select2": "latest"
33-
}
34-
```
30+
`$ grunt watch:karma`
31+
32+
This will start a Karma server in the background and run unit tests in Firefox and PhantomJS whenever the source code or spec file is saved.
33+
34+
# Usage
35+
36+
We use [bower](https://github.com/bower/bower) for dependency management. Install AngularUI Select2 into your project by running the command
3537

36-
To your `bower.json` file. Then run
38+
`$ bower install angular-ui-select2`
3739

38-
bower install
40+
If you use a `bower.json` file in your project, you can have Bower save ui-select2 as a dependency by passing the `--save` or `--save-dev` flag with the above command.
3941

40-
This will copy the ui-select2 files into your `components` folder, along with its dependencies. Load the script files in your application:
42+
This will copy the ui-select2 files into your `bower_components` folder, along with its dependencies. Load the script files in your application:
4143
```html
42-
<link rel="stylesheet" href="components/select2/select2.css">
43-
<script type="text/javascript" src="components/jquery/jquery.js"></script>
44-
<script type="text/javascript" src="components/select2/select2.js"></script>
45-
<script type="text/javascript" src="components/angular/angular.js"></script>
46-
<script type="text/javascript" src="components/angular-ui-select2/src/select2.js"></script>
44+
<link rel="stylesheet" href="bower_components/select2/select2.css">
45+
<script type="text/javascript" src="bower_components/jquery/jquery.js"></script>
46+
<script type="text/javascript" src="bower_components/select2/select2.js"></script>
47+
<script type="text/javascript" src="bower_components/angular/angular.js"></script>
48+
<script type="text/javascript" src="bower_components/angular-ui-select2/src/select2.js"></script>
4749
```
4850

4951
(Note that `jquery` must be loaded before `angular` so that it doesn't use `jqLite` internally)

package.json

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
{
22
"author": "https://github.com/angular-ui/ui-select2/graphs/contributors",
33
"name": "angular-ui-select2",
4-
"keywords": ["angular", "angularui", "select2"],
4+
"keywords": [
5+
"angular",
6+
"angularui",
7+
"select2"
8+
],
59
"description": "AngularUI - The companion suite for AngularJS",
610
"version": "0.0.2",
711
"homepage": "http://angular-ui.github.com",
@@ -14,8 +18,11 @@
1418
},
1519
"dependencies": {},
1620
"devDependencies": {
17-
"grunt-recess": "~0.1.3",
1821
"async": "0.1.x",
19-
"karma": "~0"
22+
"grunt": "~0.4.1",
23+
"grunt-contrib-jshint": "~0.6.4",
24+
"grunt-contrib-watch": "~0.5.3",
25+
"grunt-karma": "~0.6.2",
26+
"karma": "~0.10.2"
2027
}
2128
}

src/select2.js

+27-21
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ angular.module('ui.select2', []).value('uiSelect2Config', {}).directive('uiSelec
1717
repeatOption,
1818
repeatAttr,
1919
isSelect = tElm.is('select'),
20-
isMultiple = (tAttrs.multiple !== undefined);
20+
isMultiple = angular.isDefined(tAttrs.multiple);
2121

2222
// Enable watching of the options dataset if in use
2323
if (tElm.is('select')) {
@@ -39,21 +39,21 @@ angular.module('ui.select2', []).value('uiSelect2Config', {}).directive('uiSelec
3939
var convertToAngularModel = function(select2_data) {
4040
var model;
4141
if (opts.simple_tags) {
42-
model = []
42+
model = [];
4343
angular.forEach(select2_data, function(value, index) {
44-
model.push(value.id)
45-
})
44+
model.push(value.id);
45+
});
4646
} else {
47-
model = select2_data
47+
model = select2_data;
4848
}
49-
return model
50-
}
49+
return model;
50+
};
5151

5252
/*
5353
Convert from Angular view-model to Select2 view-model.
5454
*/
5555
var convertToSelect2Model = function(angular_data) {
56-
var model = []
56+
var model = [];
5757
if (!angular_data) {
5858
return model;
5959
}
@@ -64,12 +64,12 @@ angular.module('ui.select2', []).value('uiSelect2Config', {}).directive('uiSelec
6464
angular_data,
6565
function(value, index) {
6666
model.push({'id': value, 'text': value});
67-
})
67+
});
6868
} else {
6969
model = angular_data;
7070
}
71-
return model
72-
}
71+
return model;
72+
};
7373

7474
if (isSelect) {
7575
// Use <select multiple> instead
@@ -83,13 +83,13 @@ angular.module('ui.select2', []).value('uiSelect2Config', {}).directive('uiSelec
8383
// Watch the model for programmatic changes
8484
scope.$watch(tAttrs.ngModel, function(current, old) {
8585
if (!current) {
86-
return
86+
return;
8787
}
88-
if (current == old) {
89-
return
88+
if (current === old) {
89+
return;
9090
}
91-
controller.$render()
92-
}, true)
91+
controller.$render();
92+
}, true);
9393
controller.$render = function () {
9494
if (isSelect) {
9595
elm.select2('val', controller.$viewValue);
@@ -112,7 +112,9 @@ angular.module('ui.select2', []).value('uiSelect2Config', {}).directive('uiSelec
112112
// Watch the options dataset for changes
113113
if (watch) {
114114
scope.$watch(watch, function (newVal, oldVal, scope) {
115-
if (!newVal) return;
115+
if (!newVal) {
116+
return;
117+
}
116118
// Delayed so that the options have time to be rendered
117119
$timeout(function () {
118120
elm.select2('val', controller.$viewValue);
@@ -124,7 +126,7 @@ angular.module('ui.select2', []).value('uiSelect2Config', {}).directive('uiSelec
124126

125127
// Update valid and dirty statuses
126128
controller.$parsers.push(function (value) {
127-
var div = elm.prev()
129+
var div = elm.prev();
128130
div
129131
.toggleClass('ng-invalid', !controller.$valid)
130132
.toggleClass('ng-valid', controller.$valid)
@@ -138,7 +140,9 @@ angular.module('ui.select2', []).value('uiSelect2Config', {}).directive('uiSelec
138140
if (!isSelect) {
139141
// Set the view and model value and update the angular template manually for the ajax/multiple select2.
140142
elm.bind("change", function () {
141-
if (scope.$$phase) return;
143+
if (scope.$$phase) {
144+
return;
145+
}
142146
scope.$apply(function () {
143147
controller.$setViewValue(
144148
convertToAngularModel(elm.select2('data')));
@@ -185,9 +189,11 @@ angular.module('ui.select2', []).value('uiSelect2Config', {}).directive('uiSelec
185189
controller.$render();
186190

187191
// Not sure if I should just check for !isSelect OR if I should check for 'tags' key
188-
if (!opts.initSelection && !isSelect)
192+
if (!opts.initSelection && !isSelect) {
189193
controller.$setViewValue(
190-
convertToAngularModel(elm.select2('data')));
194+
convertToAngularModel(elm.select2('data'))
195+
);
196+
}
191197
});
192198
};
193199
}

test/karma.conf.js

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// Karma configuration
2+
// Generated on Tue Sep 17 2013 06:59:46 GMT-0400 (EDT)
3+
4+
module.exports = function(config) {
5+
config.set({
6+
7+
// base path, that will be used to resolve files and exclude
8+
basePath: '..',
9+
10+
11+
// frameworks to use
12+
frameworks: ['jasmine'],
13+
14+
15+
// list of files / patterns to load in the browser
16+
files: [
17+
// Dependencies
18+
'bower_components/jquery/jquery.js',
19+
'bower_components/angular/angular.js',
20+
'bower_components/angular-mocks/angular-mocks.js',
21+
'bower_components/select2/select2.js',
22+
23+
// Source Code
24+
'src/select2.js',
25+
26+
// Test Specs
27+
'test/*Spec.js'
28+
],
29+
30+
31+
// list of files to exclude
32+
exclude: [
33+
34+
],
35+
36+
37+
// test results reporter to use
38+
// possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
39+
reporters: ['progress'],
40+
41+
42+
// web server port
43+
port: 9876,
44+
45+
46+
// enable / disable colors in the output (reporters and logs)
47+
colors: true,
48+
49+
50+
// level of logging
51+
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
52+
logLevel: config.LOG_INFO,
53+
54+
55+
// enable / disable watching file and executing tests whenever any file changes
56+
autoWatch: false,
57+
58+
59+
// Start these browsers, currently available:
60+
// - Chrome
61+
// - ChromeCanary
62+
// - Firefox
63+
// - Opera
64+
// - Safari (only Mac)
65+
// - PhantomJS
66+
// - IE (only Windows)
67+
browsers: ['Chrome', 'Firefox'],
68+
69+
70+
// If browser does not capture in given timeout [ms], kill it
71+
captureTimeout: 60000,
72+
73+
74+
// Continuous Integration mode
75+
// if true, it capture browsers, run tests and exit
76+
singleRun: false
77+
78+
79+
});
80+
};

test/select2Spec.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -331,12 +331,12 @@ describe('uiSelect2', function () {
331331

332332
it('updated the view when model changes with complex object', function(){
333333
scope.foo = [{'id': '0', 'text': '0'}];
334-
scope.options['multiple'] = true
334+
scope.options['multiple'] = true;
335335
var element = compile('<input ng-model="foo" ui-select2="options">');
336-
scope.$digest()
336+
scope.$digest();
337337

338-
scope.foo.push({'id': '1', 'text': '1'})
339-
scope.$digest()
338+
scope.foo.push({'id': '1', 'text': '1'});
339+
scope.$digest();
340340

341341
expect(element.select2('data')).toEqual(
342342
[{'id': '0', 'text': '0'}, {'id': '1', 'text': '1'}]);
@@ -346,9 +346,9 @@ describe('uiSelect2', function () {
346346
describe('simple_tags', function() {
347347

348348
beforeEach(function() {
349-
scope.options['multiple'] = true
350-
scope.options['simple_tags'] = true
351-
scope.options['tags'] = []
349+
scope.options['multiple'] = true;
350+
scope.options['simple_tags'] = true;
351+
scope.options['tags'] = [];
352352
});
353353

354354
it('Initialize the select2 view based on list of strings.', function() {
@@ -399,7 +399,7 @@ describe('uiSelect2', function () {
399399
element.select2('data', [
400400
{'id':'tag1', 'text': 'tag1'},
401401
{'id':'tag2', 'text': 'tag2'}
402-
])
402+
]);
403403
element.trigger('change');
404404

405405
expect(scope.foo).toEqual(['tag1', 'tag2']);

0 commit comments

Comments
 (0)