diff --git a/.bowerrc b/.bowerrc deleted file mode 100644 index deceb62..0000000 --- a/.bowerrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "directory": "bower_components" -} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 8409212..0e586cd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ bower_components/ node_modules/ coverage/ +dist/ +out/ \ No newline at end of file diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..ad23bcc --- /dev/null +++ b/.jshintrc @@ -0,0 +1,23 @@ +{ + "boss": true, + "browser": true, + "eqnull": true, + "expr": true, + "globalstrict": true, + "immed": true, + "laxbreak": true, + "loopfunc": true, + "newcap": true, + "noarg": true, + "noempty": true, + "nonew": true, + "quotmark": true, + "smarttabs": true, + "sub": true, + "trailing": true, + "undef": true, + "unused": true, + "globals": { + "angular": false + } +} diff --git a/.travis.yml b/.travis.yml index e4e6c60..1a2df89 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,39 @@ language: node_js node_js: - - "0.8" - +- '0.10' before_install: - - export DISPLAY=:99.0 - - sh -e /etc/init.d/xvfb start - - npm install -g bower grunt-cli - - npm install - - bower install - -script: "grunt" \ No newline at end of file +- export DISPLAY=:99.0 +- sh -e /etc/init.d/xvfb start +- npm install -qg bower grunt-cli +- npm install -q +- bower install +after_success: +- ./node_modules/angular-ui-publisher/travis/authentication.sh || exit 0 +- grunt dist build:gh-pages publish:gh-pages build:bower publish:bower +script: grunt +env: + global: + - REPO="git@github.com:angular-ui/ui-sortable.git" + - secure: lv6/NYEdeaQi/ITVGbmWLdj2LoHjrMaF511YoDOOEWjdtCZPUmIciMYDvDidaLzr5NKgtaQCzGouHIgbdM2r+blJndTB+fydXYw3nq9qvRsXRGbWH0TY2KtdB++73NhomHN2kOYAx7IOW7XN+StWG6kdBFJ6lDOZl9vOZTHnHvE= + - secure: A6zLTHw99hvJ37FNKPnW4y6Eu/G+1M7NEw4vgWDlyH96RB0QYYvRKuHVn68FRBtHSdcaFzuANjzxeE0QEBBhq4kM4AjsQtveBHJcTBDZGnzZB7krH1E8yrNH70EWI8b3bXsWzUaYeNgUMFJpFa1pEMWq2rCe0CwEFVHf8TlF7MI= + - secure: BEWMRv9ET7fXabDkAvRQJBsIziyDeYrVkXDEINgdDwaoNclYtDSnxyYMG1wAcoNM6Znb8MdcmZm2SaOUOxIwplukomh1i8oT6wXeEl+vaYoCS6kz9iwcqgE0rFx9Zo+9q+UCvst30aB//XtVt71tbpKYaNTilZH2U6gvmUxYUAM= + - secure: SbIj+dXPq3y+cREpT+GoXBflKr2SmonL+ini3Q+7EL+82xMbqnTYRRdVvSBOAbK35fskBgDec91kuF2jKKvi3n2kYLWqYC5a6MteMsD/Ne7ntmebSZ4xIoI2CnHnYMoh8X5r2R5ykAu9phKDb6ujNol2bSI/2UBeSXse1ROp6M8= + - secure: RCFXr57oVjSOnM28rYMSfi4xlU70R5bjbDU+NUhQ+Mw7S1Bz1B0F+ZwMRuXDz2GnBnA+2Vu6i6qY0TWxfd7SAkG7+mW8hKc7OrHjYSt6tPPeCfwx6fcnFF6wxWR5fOt47aX4sNnOkaAoPQa2rf6uPHknTP0mVJgX//hsS++8orw= + - secure: VPb2CQUyWC0BY5Pf2qJpUBEV3nPvvxeQYMZ/woVy53TN+EL0n0un70Ia9ddGBljcRLYht08lRnf8SMnSkpCyqtDGVY/XskzdR7D2JJk0DoBoShPHeVPz6wb+Za1F/syp1S+P4L+9+ZTrDFwkXoTN6ZEVoOqh8S5SW5lyxpBcOjo= + - secure: fGkAkjv8+0UEpmVDK2tDsJ2b7pAazNkZnBtIB+dLNDxeIPp/o75TiIN52dsjYMS4v8AhPX9XEGgURHKO4Tt3CJ42oAV3SXFSSKZ+HUad0YzEw0SCLsMJOJvGSyg8A9d811//KpDZkSvNTLRER9kW+ONVGWkaqDzZk9JNAiZQ21E= + - secure: moG6EmijG8fnkSEKWT5939qubV7bupNHiR1f61HAaC4dFN2fnQuqzamBlRTmdISOuhFKkMAZRt9ZpRjeOTwcGzE+PV2WkbLzZggn19uPV/4J6cm3MBDhnbJfrTnNCD+XoxfgJezwWL+yA+OTKOjKoli/c2j3gA18lHxL8RGGfWA= + - secure: ey2lvN+BsXGwYm8uMuVl22fv6ABqdqr+wEGsXVq0IwMfoyifXu7Zjbqq3dbxwOADlm2BpuBM1EMOh4b3J5Xae5KbkZ1olh8wbTT07XN6GdRyKoxRgkxORyjQe35uPpxNXPG/4MDPGvOer4tP205GSSET7GzXgTjeoUP/Wn04l3U= + - secure: BkaTcpkvyph2ktmqHmWV2sM+3U2X/Np7LH6CjV/up1tyUqLUVOg7KcxVnDhrfrzxeQQqDv8CX4bkE9OIe0PrIU5FzRDAlxmEA1n8iR/ZFQdLmdLXIT5Aq58oEggyB3GvmojOLSB2MT2jPucz+RpftaglaUtxwa20nxryigEDOdU= + - secure: TQqMgKNva40V429OmdCpFHiAXc86wIhnSN4MYSKpWKb4vmG7pL75ycjYCxADpKJjOjGb4JYk/UZOk/3PIWi2g0j/thNEIK48jak7dtA7I9RZ/pKA6JN4LxaSlcsrOUhFfWAzfchrqpbHCwvzKlbFJmulRXKAeFbqXmzf6IaUVZg= + - secure: CbGh34phZ9Fbzow1JmtDcbbfu5si7piJLUFFAxGlXlu7lYVp5XpgCJ40uIpbzArZ8ZYaD9ZtoCqBgW5dDKRMUdbyobIqbeIcnljAXrHR+M6FonLuao+TLOe9s2k1fThU4Pdxm9aGedz63UwaTdibCY+mFK7jNptxkfO4RAsnsuw= + - secure: i41+wqwnBiQ+OICjPcOFFTkkznqS6E3sVay9plI7RSQJjN4hj9Nvmarr6l9dqIUUSuIrkZVfynvpOezPT6mrOJZulpGOamJMBfueJ03Vk2pT8vtRRMh1ICyNSz6ZznORa7tZYOM+oI8Bi9gXJzVfxWvTF958XyVgX6GeYEWYCME= + - secure: gH09SKPIpoUCci3DGJ6jQYIOCtGuU12pUyMNJbws+/AKKgLTfozPqbsYZ/CWZOC5Wh/dvTiW0tRsZDYRfq1MWosoDjd1QxlzlhvqxQ120F1LtLHm9IPgrVdHBzG1dJdKUIkgYL+4pwgMbPJUWDfJduxd4iI1eZzqYEWR+lapjEE= + - secure: LHeYrBZ1mfPRi4xEv1pc+HlQGtUtsRFUHLMel7UafILSfjhqRu0p0uH0RvqjB4ctrjufqrpZh+C5iAitKULoX7drRZABxR4fUAGUT7UADJ3YAFuhseNNpNPa5LOqhcsxA4t+oFsnZq+/1HvGAXi/tkrIJlogiNdIO5/EcwI2GOc= + - secure: dq9Bjf+44cEeOqdVT8za+3uCGXcjAZ1DdkSZ1bp7qlEcFsV4xjgwa1Qa4XWl9D5x1ZjuQ/CG2Hbcm1N+CW9UtmJsxqmQye+WkwD14HzKoRTQubMW2woiTuPWj2HcZB03S24f9r83kxCyvdhBeNcNgqPYZByQerlWhd8mKzKvLq8= + - secure: bMOOsktaSAshyBJQMlLZMBVoHguYJRFM0FUkskhIi9OTXsJajBAw5TYqsSlEJcMb65tgWR0KzHYOVKesoZvq5pyWkIANIJduoGwAuhY6loMmhY+kBF4ZKx6d+V1pnyzT5uW/0Jn+nN6XiuXHGx/fjppAvi/AYd05+bRYvAvYoRQ= + - secure: Nit2R7+Ob/jDz0i/3iUrcMjskkwlr/Bp+xWYm9MS/9LSG19N+eV/1McNEe1joFUeQ29IfZUU522u27Twbf9h10X/4um99vSwxUkqyTpR5Gl8N7bu51bbRzGwTFqAQoxiIc2bEpSwVyql0okLnYsaZVDOjlyuAqZ1RRj+xBfcUrI= + - secure: ZoIMbOS9tUpCEZyWGEzkNITPvPorJ+d7n3yMGJqhD6Ud7n6oFyLskT7JECZ4cUiykVaWsAHGMN+xxYLUkAJLdhd2gE3reN+8JrSjJb32W0Sf+5z1ajcwWBsZu4nyxRpPo2QZduS7lU2M0+YdFs8qG7gEhploFDu7hZOI2RaCkTo= + - secure: DZhkAksHSU8MGN0dISwGWA2uuMEvxpeSmqJu2fpPTei//n5l/n+RqlfYH8hUKdMf87RBpXRY1VpHiFYpkNYsmf903gw3kdRWhW07hG3Yt9hXc+YIR0OK6KZ5sb/XZi/ZkWrPEInAL2Yol00e6+U13134SZlPE84P6ktXiKKtlMc= + - secure: Cy34UQZ7/9toUKV6905XYeXIaFdDRhLb+ibEbLnjoo3ifeApNaecc1l4aBN88HN6nKnX1TKSZyiETwCpCWCee2d7KTi4IhSFTAa+SVUTV6BmikhdUs6MwemyreyWFlxZD32huZKyWU9ZEAwwQ0Oq9gPqECWWZkdT4LInF6SLWLY= + - secure: E9gahGC9Swvy83Kos9LhFsxZp/zBI6Ll9lqQd6HxT7YSXj2YeoxSMCsF629bODPdtuMirhmFqReKZKL1lDpJBswr1sFtnmVavSwVBW4v/CIAQu0ENC85Knv1wgoAcl7cRisWaueSHJ0DyNstZZWGNWryIINg9zjFdrOSztDvoN8= + - secure: UxCvWwq2GcUdL3BtJyRMEFPHPRGIdPPLthThmWrmUE7dnblpDUdWVXKc62f7Y42qtHlhYh1EjxX0GJFcS1F0Lfge0e0cxDNWBATBoLKpC67kTyz/cUgqFEv6tsbkziBtbOrBuy6/LMZly1BqG/3fIDEJezkKOIqHF+pdApvAC/8= diff --git a/README.md b/README.md index 7020417..7af5ee7 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ui-sortable directive [![Build Status](https://travis-ci.org/angular-ui/ui-sortable.png)](https://travis-ci.org/angular-ui/ui-sortable) +# UI.Sortable directive [![Build Status](https://travis-ci.org/angular-ui/ui-sortable.png)](https://travis-ci.org/angular-ui/ui-sortable) This directive allows you to sort array with drag & drop. @@ -80,3 +80,33 @@ Feel free to edit any of them for your needs (don't forget to also update the li - [Simple Demo](http://codepen.io/thgreasi/pen/BlFLp) - [Connected Lists](http://codepen.io/thgreasi/pen/apwsb) + + +## Testing + +We use Karma and jshint to ensure the quality of the code. The easiest way to run these checks is to use grunt: + +```sh +npm install -g grunt-cli +npm install && bower install +grunt +``` + +The karma task will try to open Firefox and Chrome as browser in which to run the tests. Make sure this is available or change the configuration in `test\karma.conf.js` + + +### Grunt Serve + +We have one task to serve them all ! + +```sh +grunt serve +``` + +It's equal to run separately: + +* `grunt connect:server` : giving you a development server at [http://127.0.0.1:8000/](http://127.0.0.1:8000/). + +* `grunt karma:server` : giving you a Karma server to run tests (at [http://localhost:9876/](http://localhost:9876/) by default). You can force a test on this server with `grunt karma:unit:run`. + +* `grunt watch` : will automatically test your code and build your demo. You can demo generation with `grunt build:gh-pages`. diff --git a/demo/demo.css b/demo/demo.css index 5522a62..95cc741 100644 --- a/demo/demo.css +++ b/demo/demo.css @@ -20,10 +20,6 @@ /*** Extra ***/ -body { - font-family: Verdana, 'Trebuchet ms', Tahoma; -} - .logList { margin-top: 20px; width: 250px; @@ -41,11 +37,6 @@ body { background-color: #FFF; } -.container { - width:300px; - margin: auto; +ul[ui-sortable] { + float: right; } - -h2 { - text-align: center; -} \ No newline at end of file diff --git a/demo/demo.html b/demo/demo.html index a6c681b..7be47d3 100644 --- a/demo/demo.html +++ b/demo/demo.html @@ -1,61 +1,14 @@ - - - - - - - - - AngularUI - Sortable Demo - - - - - - - - - - -
-

ui.sortable demo

- - - - +
+
+
+
    +
  • {{item.text}}
  • +
+
+
+
    +
  • {{entry.Text}}
  • +
+
- - +
\ No newline at end of file diff --git a/demo/demo.js b/demo/demo.js new file mode 100644 index 0000000..5055e9c --- /dev/null +++ b/demo/demo.js @@ -0,0 +1,30 @@ +'use strict'; + +var myapp = angular.module('sortableApp', ['ui.sortable']); + +myapp.controller('sortableController', function ($scope) { + var tmpList = []; + + for (var i = 1; i <= 6; i++){ + tmpList.push({ + text: 'Item ' + i, + value: i + }); + } + + $scope.list = tmpList; + + + $scope.sortingLog = []; + + $scope.sortableOptions = { + // called after a node is dropped + stop: function(e, ui) { + var logEntry = { + ID: $scope.sortingLog.length + 1, + Text: 'Moved element: ' + ui.item.scope().item.text + }; + $scope.sortingLog.push(logEntry); + } + }; +}); \ No newline at end of file diff --git a/gruntFile.js b/gruntFile.js index 798cbf5..fabd428 100644 --- a/gruntFile.js +++ b/gruntFile.js @@ -1,46 +1,141 @@ +'use strict'; + module.exports = function(grunt) { - grunt.loadNpmTasks('grunt-testacular'); - grunt.loadNpmTasks('grunt-contrib-jshint'); + require('load-grunt-tasks')(grunt); // Default task. - grunt.registerTask('default', ['jshint', 'testacular']); + grunt.registerTask('default', ['jshint', 'karma:unit']); + grunt.registerTask('serve', ['karma:continuous', 'dist', 'build:gh-pages', 'connect:continuous', 'watch']); + grunt.registerTask('dist', ['ngmin', 'uglify']); - var testacularConfig = function(configFile, customOptions) { - var options = { - configFile: configFile, - keepalive: true - }; - var travisOptions = process.env.TRAVIS && { - browsers: ['Firefox'], - reporters: 'dots' + + // HACK TO ACCESS TO THE COMPONENT PUBLISHER + function fakeTargetTask(prefix){ + return function(){ + + if (this.args.length !== 1) return grunt.log.fail('Just give the name of the ' + prefix + ' you want like :\ngrunt ' + prefix + ':bower'); + + var done = this.async(); + var spawn = require('child_process').spawn; + spawn('./node_modules/.bin/gulp', [ prefix, '--branch='+this.args[0] ].concat(grunt.option.flags()), { + cwd : './node_modules/angular-ui-publisher', + stdio: 'inherit' + }).on('close', done); }; + } + + grunt.registerTask('build', fakeTargetTask('build')); + grunt.registerTask('publish', fakeTargetTask('publish')); + // + + + // HACK TO MAKE TRAVIS WORK + var testConfig = function(configFile, customOptions) { + var options = { configFile: configFile, singleRun: true }; + var travisOptions = process.env.TRAVIS && { browsers: ['Firefox', 'PhantomJS'], reporters: ['dots'] }; return grunt.util._.extend(options, customOptions, travisOptions); }; + // + // Project configuration. grunt.initConfig({ - testacular: { - unit: { - options: testacularConfig('test/test.conf.js') - } + pkg: grunt.file.readJSON('package.json'), + meta: { + banner: ['/**', + ' * <%= pkg.name %> - <%= pkg.description %>', + ' * @version v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>', + ' * @link <%= pkg.homepage %>', + ' * @license <%= pkg.license %>', + ' */', + ''].join('\n') }, - jshint: { - files: ['src/**/*.js', 'test/**/*.js', 'demo/**/*.js', '!test/libs/*.js'], + + connect: { options: { - curly: true, - eqeqeq: true, - immed: true, - //indent: 2, - latedef: true, - newcap: true, - noarg: true, - sub: true, - boss: true, - eqnull: true, - globals: {} + base : 'out/built/gh-pages', + open: true, + livereload: true + }, + server: { options: { keepalive: true } }, + continuous: { options: { keepalive: false } } + }, + + karma: { + unit: testConfig('test/karma.conf.js'), + server: {configFile: 'test/karma.conf.js'}, + continuous: {configFile: 'test/karma.conf.js', background: true } + }, + + jshint: { + src: { + files:{ src : ['src/**/*.js', 'demo/**/*.js'] }, + options: { jshintrc: '.jshintrc' } + }, + test: { + files:{ src : [ 'test/*.spec.js', 'gruntFile.js'] }, + options: grunt.util._.extend({}, grunt.file.readJSON('.jshintrc'), { + node: true, + globals: { + angular: false, + inject: false, + '$': false, + + jasmine: false, + afterEach: false, + beforeEach: false, + ddescribe: false, + describe: false, + expect: false, + iit: false, + it: false, + spyOn: false, + xdescribe: false, + xit: false + } + }) + } + }, + + uglify: { + options: {banner: '<%= meta.banner %>'}, + build: { + expand: true, + cwd: 'dist', + src: ['*.js'], + ext: '.min.js', + dest: 'dist' + } + }, + + ngmin: { + main: { + expand: true, + cwd: 'src', + src: ['*.js'], + dest: 'dist' + } + }, + + watch: { + src: { + files: ['src/*'], + tasks: ['jshint:src', 'karma:unit:run', 'dist', 'build:gh-pages'] + }, + test: { + files: ['test/*.js'], + tasks: ['jshint:test', 'karma:unit:run'] + }, + demo: { + files: ['demo/*', 'publish.js'], + tasks: ['jshint', 'build:gh-pages'] + }, + livereload: { + files: ['out/built/gh-pages/**/*'], + options: { livereload: true } } } }); -}; \ No newline at end of file +}; diff --git a/package.json b/package.json index 9b7870d..7491aa1 100644 --- a/package.json +++ b/package.json @@ -5,12 +5,28 @@ "author": "https://github.com/angular-ui/ui-sortable/graphs/contributors", "license": "MIT", "homepage": "http://angular-ui.github.com", - "main": "./src/sortable.js", + "main": "./sortable.js", "dependencies": {}, "devDependencies": { - "grunt": "~0.4.1", - "grunt-testacular": "~0.3.0", - "grunt-contrib-jshint": "~0.2.0" + "angular-ui-publisher": "1.x", + "grunt": "~0.4.x", + "grunt-contrib-connect": "0.5.x", + "grunt-contrib-jshint": "0.8.x", + "grunt-contrib-uglify": "0.2.x", + "grunt-contrib-watch": "0.5.x", + "grunt-karma": "0.6.x", + "grunt-ngmin": "0.0.x", + "karma": "0.10.x", + "karma-chrome-launcher": "0.1.x", + "karma-coffee-preprocessor": "0.1.x", + "karma-firefox-launcher": "0.1.x", + "karma-html2js-preprocessor": "0.1.x", + "karma-jasmine": "0.1.x", + "karma-phantomjs-launcher": "0.1.x", + "karma-requirejs": "0.2.x", + "karma-script-launcher": "0.1.x", + "load-grunt-tasks": "0.2.x", + "requirejs": "2.1.x" }, "scripts": {}, "repository": { diff --git a/publish.js b/publish.js new file mode 100644 index 0000000..7142a3c --- /dev/null +++ b/publish.js @@ -0,0 +1,31 @@ +/* jshint node:true */ + +'use strict'; + +var fs = require('fs'); +var path = require('path'); + +module.exports = function() { + + var js_dependencies =[ + 'bower_components/jquery-ui/ui/jquery-ui.js' + ]; + + var css_dependencies = [ + 'bower_components/jquery-ui/themes/smoothness/jquery-ui.css' + ]; + + function putThemInVendorDir (filepath) { + return 'vendor/' + path.basename(filepath); + } + + return { + humaName : 'UI.Sortable', + repoName : 'ui-sortable', + inlineHTML : fs.readFileSync(__dirname + '/demo/demo.html'), + inlineJS : fs.readFileSync(__dirname + '/demo/demo.js'), + css: css_dependencies.map(putThemInVendorDir).concat(['demo/demo.css']), + js : js_dependencies.map(putThemInVendorDir).concat(['dist/sortable.js']), + tocopy : css_dependencies.concat(js_dependencies) + }; +}; diff --git a/src/sortable.js b/src/sortable.js index e650014..a8a1cf1 100644 --- a/src/sortable.js +++ b/src/sortable.js @@ -1,3 +1,5 @@ +'use strict'; + /* jQuery UI Sortable plugin wrapper @@ -12,7 +14,7 @@ angular.module('ui.sortable', []) link: function(scope, element, attrs, ngModel) { function combineCallbacks(first,second){ - if( second && (typeof second === "function") ){ + if( second && (typeof second === 'function') ){ return function(e,ui){ first(e,ui); second(e,ui); @@ -30,7 +32,7 @@ angular.module('ui.sortable', []) stop:null, update:null }; - + var apply = function(e, ui) { if (ui.item.sortable.resort || ui.item.sortable.relocate) { scope.$apply(); @@ -42,7 +44,7 @@ angular.module('ui.sortable', []) if (ngModel) { ngModel.$render = function() { - element.sortable( "refresh" ); + element.sortable( 'refresh' ); }; callbacks.start = function(e, ui) { @@ -85,13 +87,13 @@ angular.module('ui.sortable', []) } }; - scope.$watch(attrs.uiSortable, function(newVal, oldVal){ + scope.$watch(attrs.uiSortable, function(newVal){ angular.forEach(newVal, function(value, key){ if( callbacks[key] ){ // wrap the callback value = combineCallbacks( callbacks[key], value ); - + if ( key === 'stop' ){ // call apply after stop value = combineCallbacks( value, apply ); @@ -106,7 +108,7 @@ angular.module('ui.sortable', []) opts[key] = combineCallbacks(value, opts[key]); }); - + // call apply after stop opts.stop = combineCallbacks( opts.stop, apply ); diff --git a/test/karma.conf.js b/test/karma.conf.js new file mode 100644 index 0000000..e2a0853 --- /dev/null +++ b/test/karma.conf.js @@ -0,0 +1,75 @@ +// Karma configuration +// Generated on Sat Dec 28 2013 20:27:08 GMT+0100 (CET) + +module.exports = function(config) { + config.set({ + + // base path, that will be used to resolve files and exclude + basePath: '..', + + + // frameworks to use + frameworks: ['jasmine'], + + + // list of files / patterns to load in the browser + files: [ + 'bower_components/jquery/jquery.js', + 'bower_components/jquery-simulate/jquery.simulate.js', + 'test/libs/jquery.simulate.dragandrevert.js', + 'bower_components/jquery-ui/ui/jquery-ui.js', + 'bower_components/angular/angular.js', + 'bower_components/angular-mocks/angular-mocks.js', + 'src/sortable.js', + 'test/*.spec.js' + ], + + + // list of files to exclude + exclude: [ + + ], + + + // test results reporter to use + // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage' + reporters: ['progress'], + + + // web server port + port: 9876, + + + // enable / disable colors in the output (reporters and logs) + colors: true, + + + // level of logging + // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG + logLevel: config.LOG_INFO, + + + // enable / disable watching file and executing tests whenever any file changes + autoWatch: false, + + + // Start these browsers, currently available: + // - Chrome + // - ChromeCanary + // - Firefox + // - Opera (has to be installed with `npm install karma-opera-launcher`) + // - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`) + // - PhantomJS + // - IE (only Windows; has to be installed with `npm install karma-ie-launcher`) + browsers: ['Chrome', 'Firefox', '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/test/sortable.spec.js b/test/sortable.spec.js index da60de6..21b10fc 100644 --- a/test/sortable.spec.js +++ b/test/sortable.spec.js @@ -1,3 +1,5 @@ +'use strict'; + describe('uiSortable', function() { // Ensure the sortable angular module is loaded @@ -21,8 +23,8 @@ describe('uiSortable', function() { it('should have a ui-sortable class', function() { inject(function($compile, $rootScope) { var element; - element = $compile("")($rootScope); - expect(element.hasClass("ui-sortable")).toBeTruthy(); + element = $compile('')($rootScope); + expect(element.hasClass('ui-sortable')).toBeTruthy(); }); }); @@ -31,7 +33,7 @@ describe('uiSortable', function() { var element; element = $compile('')($rootScope); $rootScope.$apply(function() { - $rootScope.items = ["One", "Two", "Three"]; + $rootScope.items = ['One', 'Two', 'Three']; }); expect($log.info.logs.length).toEqual(1); @@ -62,7 +64,7 @@ describe('uiSortable', function() { var element; element = $compile('')($rootScope); $rootScope.$apply(function() { - $rootScope.items = ["One", "Two", "Three"]; + $rootScope.items = ['One', 'Two', 'Three']; }); host.append(element); @@ -70,13 +72,13 @@ describe('uiSortable', function() { var li = element.find(':eq(1)'); var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); li.simulate('drag', { dy: dy }); - expect($rootScope.items).toEqual(["One", "Three", "Two"]); + expect($rootScope.items).toEqual(['One', 'Three', 'Two']); expect($rootScope.items).toEqualListContent(element); li = element.find(':eq(1)'); dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); li.simulate('drag', { dy: dy }); - expect($rootScope.items).toEqual(["Three", "One", "Two"]); + expect($rootScope.items).toEqual(['Three', 'One', 'Two']); expect($rootScope.items).toEqualListContent(element); $(element).remove(); @@ -92,10 +94,10 @@ describe('uiSortable', function() { items:'> .sortable' }; $rootScope.items = [ - { text: "One", sortable: true }, - { text: "Two", sortable: true }, - { text: "Three", sortable: false }, - { text: "Four", sortable: true } + { text: 'One', sortable: true }, + { text: 'Two', sortable: true }, + { text: 'Three', sortable: false }, + { text: 'Four', sortable: true } ]; }); @@ -104,25 +106,25 @@ describe('uiSortable', function() { var li = element.find(':eq(2)'); var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); li.simulate('drag', { dy: dy }); - expect($rootScope.items.map(function(x){ return x.text; })).toEqual(["One", "Two", "Three", "Four"]); + expect($rootScope.items.map(function(x){ return x.text; })).toEqual(['One', 'Two', 'Three', 'Four']); expect($rootScope.items.map(function(x){ return x.text; })).toEqualListContent(element); li = element.find(':eq(1)'); dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); li.simulate('drag', { dy: dy }); - expect($rootScope.items.map(function(x){ return x.text; })).toEqual(["One", "Three", "Four", "Two"]); + expect($rootScope.items.map(function(x){ return x.text; })).toEqual(['One', 'Three', 'Four', 'Two']); expect($rootScope.items.map(function(x){ return x.text; })).toEqualListContent(element); li = element.find(':eq(2)'); dy = -(2 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); li.simulate('drag', { dy: dy }); - expect($rootScope.items.map(function(x){ return x.text; })).toEqual(["Four", "One", "Three", "Two"]); + expect($rootScope.items.map(function(x){ return x.text; })).toEqual(['Four', 'One', 'Three', 'Two']); expect($rootScope.items.map(function(x){ return x.text; })).toEqualListContent(element); li = element.find(':eq(3)'); dy = -(2 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); li.simulate('drag', { dy: dy }); - expect($rootScope.items.map(function(x){ return x.text; })).toEqual(["Four", "Two", "One", "Three"]); + expect($rootScope.items.map(function(x){ return x.text; })).toEqual(['Four', 'Two', 'One', 'Three']); expect($rootScope.items.map(function(x){ return x.text; })).toEqualListContent(element); // also placing right above the locked node seems a bit harder !?!? @@ -137,9 +139,9 @@ describe('uiSortable', function() { element = $compile('')($rootScope); $rootScope.$apply(function() { $rootScope.opts = { - placeholder: "sortable-item-placeholder" + placeholder: 'sortable-item-placeholder' }; - $rootScope.items = ["One", "Two", "Three"]; + $rootScope.items = ['One', 'Two', 'Three']; }); host.append(element); @@ -147,13 +149,13 @@ describe('uiSortable', function() { var li = element.find(':eq(1)'); var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); li.simulate('drag', { dy: dy }); - expect($rootScope.items).toEqual(["One", "Three", "Two"]); + expect($rootScope.items).toEqual(['One', 'Three', 'Two']); expect($rootScope.items).toEqualListContent(element); li = element.find(':eq(1)'); dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); li.simulate('drag', { dy: dy }); - expect($rootScope.items).toEqual(["Three", "One", "Two"]); + expect($rootScope.items).toEqual(['Three', 'One', 'Two']); expect($rootScope.items).toEqualListContent(element); $(element).remove(); @@ -166,9 +168,9 @@ describe('uiSortable', function() { element = $compile('')($rootScope); $rootScope.$apply(function() { $rootScope.opts = { - placeholder: "sortable-item" + placeholder: 'sortable-item' }; - $rootScope.items = ["One", "Two", "Three"]; + $rootScope.items = ['One', 'Two', 'Three']; }); host.append(element); @@ -176,13 +178,13 @@ describe('uiSortable', function() { var li = element.find(':eq(1)'); var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); li.simulate('drag', { dy: dy }); - expect($rootScope.items).toEqual(["One", "Three", "Two"]); + expect($rootScope.items).toEqual(['One', 'Three', 'Two']); expect($rootScope.items).toEqualListContent(element); li = element.find(':eq(1)'); dy = -(1 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); li.simulate('drag', { dy: dy }); - expect($rootScope.items).toEqual(["Three", "One", "Two"]); + expect($rootScope.items).toEqual(['Three', 'One', 'Two']); expect($rootScope.items).toEqualListContent(element); $(element).remove(); @@ -195,9 +197,9 @@ describe('uiSortable', function() { element = $compile('')($rootScope); $rootScope.$apply(function() { $rootScope.opts = { - placeholder: "sortable-item" + placeholder: 'sortable-item' }; - $rootScope.items = ["One", "Two", "Three"]; + $rootScope.items = ['One', 'Two', 'Three']; }); host.append(element); @@ -205,25 +207,25 @@ describe('uiSortable', function() { var li = element.find(':eq(0)'); var dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); li.simulate('dragAndRevert', { dy: dy }); - expect($rootScope.items).toEqual(["One", "Two", "Three"]); + expect($rootScope.items).toEqual(['One', 'Two', 'Three']); expect($rootScope.items).toEqualListContent(element); li = element.find(':eq(0)'); dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); li.simulate('drag', { dy: dy }); - expect($rootScope.items).toEqual(["Two", "One", "Three"]); + expect($rootScope.items).toEqual(['Two', 'One', 'Three']); expect($rootScope.items).toEqualListContent(element); li = element.find(':eq(1)'); dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); li.simulate('drag', { dy: dy }); - expect($rootScope.items).toEqual(["Two", "Three", "One"]); + expect($rootScope.items).toEqual(['Two', 'Three', 'One']); expect($rootScope.items).toEqualListContent(element); li = element.find(':eq(1)'); dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); li.simulate('drag', { dy: dy }); - expect($rootScope.items).toEqual(["Two", "One", "Three"]); + expect($rootScope.items).toEqual(['Two', 'One', 'Three']); expect($rootScope.items).toEqualListContent(element); $(element).remove(); @@ -252,9 +254,9 @@ describe('uiSortable', function() { elementTop = $compile('')($rootScope); elementBottom = $compile('')($rootScope); $rootScope.$apply(function() { - $rootScope.itemsTop = ["Top One", "Top Two", "Top Three"]; - $rootScope.itemsBottom = ["Bottom One", "Bottom Two", "Bottom Three"]; - $rootScope.opts = { connectWith: ".cross-sortable" }; + $rootScope.itemsTop = ['Top One', 'Top Two', 'Top Three']; + $rootScope.itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three']; + $rootScope.opts = { connectWith: '.cross-sortable' }; }); host.append(elementTop).append(elementBottom); @@ -263,8 +265,8 @@ describe('uiSortable', function() { var li2 = elementBottom.find(':eq(0)'); var dy = EXTRA_DY_PERCENTAGE * li1.outerHeight() + (li2.position().top - li1.position().top); li1.simulate('drag', { dy: dy }); - expect($rootScope.itemsTop).toEqual(["Top Two", "Top Three"]); - expect($rootScope.itemsBottom).toEqual(["Bottom One", "Top One", "Bottom Two", "Bottom Three"]); + expect($rootScope.itemsTop).toEqual(['Top Two', 'Top Three']); + expect($rootScope.itemsBottom).toEqual(['Bottom One', 'Top One', 'Bottom Two', 'Bottom Three']); expect($rootScope.itemsTop).toEqualListContent(elementTop); expect($rootScope.itemsBottom).toEqualListContent(elementBottom); @@ -272,8 +274,8 @@ describe('uiSortable', function() { li2 = elementTop.find(':eq(1)'); dy = -EXTRA_DY_PERCENTAGE * li1.outerHeight() - (li1.position().top - li2.position().top); li1.simulate('drag', { dy: dy }); - expect($rootScope.itemsTop).toEqual(["Top Two", "Top One", "Top Three"]); - expect($rootScope.itemsBottom).toEqual(["Bottom One", "Bottom Two", "Bottom Three"]); + expect($rootScope.itemsTop).toEqual(['Top Two', 'Top One', 'Top Three']); + expect($rootScope.itemsBottom).toEqual(['Bottom One', 'Bottom Two', 'Bottom Three']); expect($rootScope.itemsTop).toEqualListContent(elementTop); expect($rootScope.itemsBottom).toEqualListContent(elementBottom); @@ -288,11 +290,11 @@ describe('uiSortable', function() { elementTop = $compile('')($rootScope); elementBottom = $compile('')($rootScope); $rootScope.$apply(function() { - $rootScope.itemsTop = ["Top One", "Top Two", "Top Three"]; - $rootScope.itemsBottom = ["Bottom One", "Bottom Two", "Bottom Three"]; + $rootScope.itemsTop = ['Top One', 'Top Two', 'Top Three']; + $rootScope.itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three']; $rootScope.opts = { - placeholder: "sortable-item-placeholder", - connectWith: ".cross-sortable" + placeholder: 'sortable-item-placeholder', + connectWith: '.cross-sortable' }; }); @@ -302,8 +304,8 @@ describe('uiSortable', function() { var li2 = elementBottom.find(':eq(0)'); var dy = EXTRA_DY_PERCENTAGE * li1.outerHeight() + (li2.position().top - li1.position().top); li1.simulate('drag', { dy: dy }); - expect($rootScope.itemsTop).toEqual(["Top Two", "Top Three"]); - expect($rootScope.itemsBottom).toEqual(["Bottom One", "Top One", "Bottom Two", "Bottom Three"]); + expect($rootScope.itemsTop).toEqual(['Top Two', 'Top Three']); + expect($rootScope.itemsBottom).toEqual(['Bottom One', 'Top One', 'Bottom Two', 'Bottom Three']); expect($rootScope.itemsTop).toEqualListContent(elementTop); expect($rootScope.itemsBottom).toEqualListContent(elementBottom); @@ -311,8 +313,8 @@ describe('uiSortable', function() { li2 = elementTop.find(':eq(1)'); dy = -EXTRA_DY_PERCENTAGE * li1.outerHeight() - (li1.position().top - li2.position().top); li1.simulate('drag', { dy: dy }); - expect($rootScope.itemsTop).toEqual(["Top Two", "Top One", "Top Three"]); - expect($rootScope.itemsBottom).toEqual(["Bottom One", "Bottom Two", "Bottom Three"]); + expect($rootScope.itemsTop).toEqual(['Top Two', 'Top One', 'Top Three']); + expect($rootScope.itemsBottom).toEqual(['Bottom One', 'Bottom Two', 'Bottom Three']); expect($rootScope.itemsTop).toEqualListContent(elementTop); expect($rootScope.itemsBottom).toEqualListContent(elementBottom); @@ -327,11 +329,11 @@ describe('uiSortable', function() { elementTop = $compile('')($rootScope); elementBottom = $compile('')($rootScope); $rootScope.$apply(function() { - $rootScope.itemsTop = ["Top One", "Top Two", "Top Three"]; - $rootScope.itemsBottom = ["Bottom One", "Bottom Two", "Bottom Three"]; + $rootScope.itemsTop = ['Top One', 'Top Two', 'Top Three']; + $rootScope.itemsBottom = ['Bottom One', 'Bottom Two', 'Bottom Three']; $rootScope.opts = { - placeholder: "sortable-item", - connectWith: ".cross-sortable" + placeholder: 'sortable-item', + connectWith: '.cross-sortable' }; }); @@ -341,8 +343,8 @@ describe('uiSortable', function() { var li2 = elementBottom.find(':eq(0)'); var dy = EXTRA_DY_PERCENTAGE * li1.outerHeight() + (li2.position().top - li1.position().top); li1.simulate('drag', { dy: dy }); - expect($rootScope.itemsTop).toEqual(["Top Two", "Top Three"]); - expect($rootScope.itemsBottom).toEqual(["Bottom One", "Top One", "Bottom Two", "Bottom Three"]); + expect($rootScope.itemsTop).toEqual(['Top Two', 'Top Three']); + expect($rootScope.itemsBottom).toEqual(['Bottom One', 'Top One', 'Bottom Two', 'Bottom Three']); expect($rootScope.itemsTop).toEqualListContent(elementTop); expect($rootScope.itemsBottom).toEqualListContent(elementBottom); @@ -350,8 +352,8 @@ describe('uiSortable', function() { li2 = elementTop.find(':eq(1)'); dy = -EXTRA_DY_PERCENTAGE * li1.outerHeight() - (li1.position().top - li2.position().top); li1.simulate('drag', { dy: dy }); - expect($rootScope.itemsTop).toEqual(["Top Two", "Top One", "Top Three"]); - expect($rootScope.itemsBottom).toEqual(["Bottom One", "Bottom Two", "Bottom Three"]); + expect($rootScope.itemsTop).toEqual(['Top Two', 'Top One', 'Top Three']); + expect($rootScope.itemsBottom).toEqual(['Bottom One', 'Bottom Two', 'Bottom Three']); expect($rootScope.itemsTop).toEqualListContent(elementTop); expect($rootScope.itemsBottom).toEqualListContent(elementBottom); @@ -384,12 +386,12 @@ describe('uiSortable', function() { $rootScope.$apply(function() { $rootScope.opts = { update: function(e, ui) { - if (ui.item.scope().item === "Two") { + if (ui.item.scope().item === 'Two') { ui.item.parent().sortable('cancel'); } } }; - $rootScope.items = ["One", "Two", "Three"]; + $rootScope.items = ['One', 'Two', 'Three']; }); host.append(element); @@ -397,19 +399,19 @@ describe('uiSortable', function() { var li = element.find(':eq(1)'); var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); li.simulate('drag', { dy: dy }); - expect($rootScope.items).toEqual(["One", "Two", "Three"]); + expect($rootScope.items).toEqual(['One', 'Two', 'Three']); expect($rootScope.items).toEqualListContent(element); li = element.find(':eq(0)'); dy = (2 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); li.simulate('drag', { dy: dy }); - expect($rootScope.items).toEqual(["Two", "Three", "One"]); + expect($rootScope.items).toEqual(['Two', 'Three', 'One']); expect($rootScope.items).toEqualListContent(element); li = element.find(':eq(2)'); dy = -(2 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); li.simulate('drag', { dy: dy }); - expect($rootScope.items).toEqual(["One", "Two", "Three"]); + expect($rootScope.items).toEqual(['One', 'Two', 'Three']); expect($rootScope.items).toEqualListContent(element); $(element).remove(); @@ -487,10 +489,10 @@ describe('uiSortable', function() { $rootScope.$apply(function() { $rootScope.opts = { update: function(e, ui) { - $rootScope.logs.push("Moved element " + ui.item.scope().item); + $rootScope.logs.push('Moved element ' + ui.item.scope().item); } }; - $rootScope.items = ["One", "Two", "Three"]; + $rootScope.items = ['One', 'Two', 'Three']; $rootScope.logs = []; }); @@ -499,8 +501,8 @@ describe('uiSortable', function() { var li = element.find(':eq(1)'); var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); li.simulate('drag', { dy: dy }); - expect($rootScope.items).toEqual(["One", "Three", "Two"]); - expect($rootScope.logs).toEqual(["Moved element Two"]); + expect($rootScope.items).toEqual(['One', 'Three', 'Two']); + expect($rootScope.logs).toEqual(['Moved element Two']); expect($rootScope.items).toEqualListContent(element); expect($rootScope.logs).toEqualListContent(logsElement); @@ -518,10 +520,10 @@ describe('uiSortable', function() { $rootScope.$apply(function() { $rootScope.opts = { stop: function(e, ui) { - $rootScope.logs.push("Moved element " + ui.item.scope().item); + $rootScope.logs.push('Moved element ' + ui.item.scope().item); } }; - $rootScope.items = ["One", "Two", "Three"]; + $rootScope.items = ['One', 'Two', 'Three']; $rootScope.logs = []; }); @@ -530,8 +532,8 @@ describe('uiSortable', function() { var li = element.find(':eq(1)'); var dy = (1 + EXTRA_DY_PERCENTAGE) * li.outerHeight(); li.simulate('drag', { dy: dy }); - expect($rootScope.items).toEqual(["One", "Three", "Two"]); - expect($rootScope.logs).toEqual(["Moved element Two"]); + expect($rootScope.items).toEqual(['One', 'Three', 'Two']); + expect($rootScope.logs).toEqual(['Moved element Two']); expect($rootScope.items).toEqualListContent(element); expect($rootScope.logs).toEqualListContent(logsElement); diff --git a/test/test.conf.js b/test/test.conf.js deleted file mode 100644 index 527a756..0000000 --- a/test/test.conf.js +++ /dev/null @@ -1,26 +0,0 @@ -basePath = '..'; -files = [ - JASMINE, - JASMINE_ADAPTER, - 'bower_components/jquery/jquery.js', - 'bower_components/jquery-simulate/jquery.simulate.js', - 'test/libs/jquery.simulate.dragandrevert.js', - 'bower_components/jquery-ui/ui/jquery-ui.js', - 'bower_components/angular/angular.js', - 'bower_components/angular-mocks/angular-mocks.js', - 'src/sortable.js', - 'test/*.spec.js' -]; -singleRun = true; -autoWatch = false; -browsers = [ 'Chrome' ]; -reporters = [ 'dots' ]; - -if (singleRun) { - reporters.push('coverage'); - preprocessors = { '**/src/*.js': 'coverage' }; - coverageReporter = { - type : 'html', - dir : 'coverage/' - }; -}