EC-CUBEにJSHintを導入してJavaScriptの品質も上げようとしてみる

EC-CUBEにJSHintを導入してJavaScriptの品質も上げようとしてみる

EC-CUBEにテストを導入する(ほぼ)1人プロジェクト
JSHintを導入してJavaScriptのおかしな部分も検知できるようにしたい

JSHintをインストール

何はともあれJSHintをまずはローカルに入れてみましょう

~~~
$ npm install jshint -g
-bash: npm: command not found
~~~

今どきnpmをインストールしてないなんてって言われそうですが入れてないのでそこからスタートです。。
あとbashですみません、zshをいちいち入れるのがめんどくさいんです。。

npmをhomebrewでインストール

homebrewの場合node.jsをインストールすれば標準でついてくるそうです

~~~
$ brew install node
==> Downloading http://nodejs.org/dist/v0.10.24/node-v0.10.24.tar.gz
######################################################################## 100.0%
==> Patching
patching file tools/gyp/pylib/gyp/xcode_emulation.py
==> ./configure –prefix=/usr/local/Cellar/node/0.10.24
==> make install
/usr/local/Cellar/node/0.10.24: 1119 files, 16M, built in 6.5 minutes
~~~

ファンがブンブンいっていましたが入りました。
改めてJSHintをインストールします

~~~
$ npm install jshint -g
npm http GET https://registry.npmjs.org/jshint
npm http 200 https://registry.npmjs.org/jshint
npm http GET https://registry.npmjs.org/jshint/-/jshint-2.5.0.tgz
npm http 200 https://registry.npmjs.org/jshint/-/jshint-2.5.0.tgz
npm http GET https://registry.npmjs.org/underscore
npm http GET https://registry.npmjs.org/cli
npm http GET https://registry.npmjs.org/minimatch
npm http GET https://registry.npmjs.org/console-browserify
npm http GET https://registry.npmjs.org/htmlparser2
npm http GET https://registry.npmjs.org/strip-json-comments
npm http GET https://registry.npmjs.org/exit
npm http GET https://registry.npmjs.org/shelljs
npm http 200 https://registry.npmjs.org/htmlparser2
npm http GET https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz
npm http 200 https://registry.npmjs.org/underscore
npm http 200 https://registry.npmjs.org/cli
npm http 200 https://registry.npmjs.org/console-browserify
npm http GET https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz
npm http GET https://registry.npmjs.org/console-browserify/-/console-browserify-0.1.6.tgz
npm http GET https://registry.npmjs.org/cli/-/cli-0.4.5.tgz
npm http 200 https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz
npm http 200 https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz
npm http 200 https://registry.npmjs.org/console-browserify/-/console-browserify-0.1.6.tgz
npm http 200 https://registry.npmjs.org/cli/-/cli-0.4.5.tgz
npm http 200 https://registry.npmjs.org/strip-json-comments
npm http GET https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-0.1.1.tgz
npm http 200 https://registry.npmjs.org/exit
npm http GET https://registry.npmjs.org/exit/-/exit-0.1.2.tgz
npm http 200 https://registry.npmjs.org/shelljs
npm http 200 https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-0.1.1.tgz
npm http 200 https://registry.npmjs.org/minimatch
npm http GET https://registry.npmjs.org/shelljs/-/shelljs-0.1.4.tgz
npm http 200 https://registry.npmjs.org/exit/-/exit-0.1.2.tgz
npm http GET https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz
npm http 200 https://registry.npmjs.org/shelljs/-/shelljs-0.1.4.tgz
npm http 200 https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz
npm http GET https://registry.npmjs.org/sigmund
npm http GET https://registry.npmjs.org/lru-cache
npm http GET https://registry.npmjs.org/glob
npm http GET https://registry.npmjs.org/domhandler
npm http GET https://registry.npmjs.org/domelementtype
npm http GET https://registry.npmjs.org/domutils
npm http GET https://registry.npmjs.org/readable-stream
npm http 200 https://registry.npmjs.org/sigmund
npm http GET https://registry.npmjs.org/sigmund/-/sigmund-1.0.0.tgz
npm http 200 https://registry.npmjs.org/lru-cache
npm http 200 https://registry.npmjs.org/glob
npm http GET https://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz
npm http GET https://registry.npmjs.org/glob/-/glob-3.2.9.tgz
npm http 200 https://registry.npmjs.org/sigmund/-/sigmund-1.0.0.tgz
npm http 200 https://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz
npm http 200 https://registry.npmjs.org/glob/-/glob-3.2.9.tgz
npm http 200 https://registry.npmjs.org/domutils
npm http GET https://registry.npmjs.org/domutils/-/domutils-1.1.6.tgz
npm http 200 https://registry.npmjs.org/readable-stream
npm http GET https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.27-1.tgz
npm http 200 https://registry.npmjs.org/domhandler
npm http 200 https://registry.npmjs.org/domutils/-/domutils-1.1.6.tgz
npm http GET https://registry.npmjs.org/domhandler/-/domhandler-2.1.0.tgz
npm http 200 https://registry.npmjs.org/domelementtype
npm http GET https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.1.tgz
npm http 200 https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.27-1.tgz
npm http 200 https://registry.npmjs.org/domhandler/-/domhandler-2.1.0.tgz
npm http 200 https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.1.tgz
npm http GET https://registry.npmjs.org/core-util-is
npm http GET https://registry.npmjs.org/isarray/0.0.1
npm http GET https://registry.npmjs.org/inherits
npm http GET https://registry.npmjs.org/string_decoder
npm http GET https://registry.npmjs.org/inherits
npm http 200 https://registry.npmjs.org/inherits
npm http 200 https://registry.npmjs.org/inherits
npm http GET https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz
npm http 200 https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz
npm http 200 https://registry.npmjs.org/isarray/0.0.1
npm http GET https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz
npm http 200 https://registry.npmjs.org/string_decoder
npm http 200 https://registry.npmjs.org/core-util-is
npm http GET https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz
npm http GET https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.25-1.tgz
npm http 200 https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz
npm http 200 https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz
npm http 200 https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.25-1.tgz
/usr/local/bin/jshint -> /usr/local/lib/node_modules/jshint/bin/jshint
[email protected] /usr/local/lib/node_modules/jshint
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected] ([email protected], [email protected])
├── [email protected] ([email protected])
└── [email protected] ([email protected], [email protected], [email protected], [email protected])
~~~

なんだかいっぱい入りました
動くのか動作を確認してみます

~~~
$ jshint -v
jshint v2.5.0
~~~

動くみたいです、試しにeccube.jsを実行してみます
~~~
$ jshint html/js/eccube.js
html/js/eccube.js: line 61, col 55, [‘menubar’] is better written in dot notation.
html/js/eccube.js: line 78, col 42, [‘closed’] is better written in dot notation.
html/js/eccube.js: line 92, col 28, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 93, col 28, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 117, col 21, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 118, col 21, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 123, col 20, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 124, col 21, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 154, col 17, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 154, col 26, [‘mode’] is better written in dot notation.
html/js/eccube.js: line 156, col 21, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 158, col 17, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 258, col 20, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 258, col 29, [‘point_check’] is better written in dot notation.
html/js/eccube.js: line 263, col 25, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 263, col 34, [‘point_check’] is better written in dot notation.
html/js/eccube.js: line 273, col 28, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 274, col 49, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 279, col 29, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 280, col 29, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 288, col 21, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 291, col 20, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 291, col 29, [‘deliv_check’] is better written in dot notation.
html/js/eccube.js: line 313, col 25, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 313, col 34, [‘deliv_check’] is better written in dot notation.
html/js/eccube.js: line 328, col 24, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 331, col 29, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 332, col 29, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 335, col 29, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 336, col 58, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 337, col 29, [‘form1’] is better written in dot notation.
html/js/eccube.js: line 423, col 39, [‘productsClassCategories’] is better written in dot notation.
html/js/eccube.js: line 427, col 39, [‘classCategories’] is better written in dot notation.
html/js/eccube.js: line 433, col 48, [‘classcategory_id2’] is better written in dot notation.
html/js/eccube.js: line 434, col 50, [‘name’] is better written in dot notation.
html/js/eccube.js: line 459, col 31, [‘productsClassCategories’] is better written in dot notation.
html/js/eccube.js: line 463, col 31, [‘classCategories’] is better written in dot notation.
html/js/eccube.js: line 469, col 42, [‘product_code’] is better written in dot notation.
html/js/eccube.js: line 472, col 49, [‘product_code’] is better written in dot notation.
html/js/eccube.js: line 481, col 35, [‘stock_find’] is better written in dot notation.
html/js/eccube.js: line 493, col 42, [‘price01’] is better written in dot notation.
html/js/eccube.js: line 493, col 89, [‘price01’] is better written in dot notation.
html/js/eccube.js: line 495, col 44, [‘price01’] is better written in dot notation.
html/js/eccube.js: line 505, col 42, [‘price02’] is better written in dot notation.
html/js/eccube.js: line 505, col 89, [‘price02’] is better written in dot notation.
html/js/eccube.js: line 507, col 44, [‘price02’] is better written in dot notation.
html/js/eccube.js: line 517, col 42, [‘point’] is better written in dot notation.
html/js/eccube.js: line 517, col 87, [‘point’] is better written in dot notation.
html/js/eccube.js: line 519, col 42, [‘point’] is better written in dot notation.
html/js/eccube.js: line 528, col 42, [‘product_class_id’] is better written in dot notation.
html/js/eccube.js: line 528, col 42, Too many errors. (89% scanned).

51 errors
~~~

51個もエラーが検出されましたが最終行はToo many errorsってなってますね(^_^;)
is better written in dot notationについてはJSLintオプション考察「inefficient subscripting」|もっこりJavaScript|ANALOGIC(アナロジック)に詳しく書いてあるので後で試しましょう

Travis CIでJSHintを実行する

Travis CIで実行するにはGruntを使う必要があるみたい??
ということみたいなのでまずはローカルにGruntを・・・

Gruntのインストール

ここからはプロジェクト単位でインストールするようなのでpackage.jsonを作る必要があるらしい(よくわかってない)
package.jsonは手で作ってもいいみたいだけどnpm initすればちゃんとしたものを作ってくれるっぽい

~~~
$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sane defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install –save` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
name: (gittest) eccube
version: (0.0.0)
description:
entry point: (index.js)
test command:
git repository: (git://github.com/sqb/EC-CUBE.git)
keywords:
author:
license: (ISC)
About to write to /Users/kimotonobuhiko/www/gittest/package.json:

{
“name”: “eccube”,
“version”: “0.0.0”,
“description”: “”,
“main”: “index.js”,
“directories”: {
“doc”: “docs”,
“test”: “tests”
},
“dependencies”: {},
“devDependencies”: {},
“scripts”: {
“test”: “echo \”Error: no test specified\” && exit 1″
},
“repository”: {
“type”: “git”,
“url”: “git://github.com/sqb/EC-CUBE.git”
},
“author”: “”,
“license”: “ISC”,
“bugs”: {
“url”: “https://github.com/sqb/EC-CUBE/issues”
},
“homepage”: “https://github.com/sqb/EC-CUBE”
}

Is this ok? (yes) yes
~~~

さてGruntを入れましょう
–save-devをつけると勝手にpackage.jsonに書き込んでくれるみたいです

~~~
$ npm install grunt –save-dev
npm WARN package.json [email protected] No description
npm WARN package.json [email protected] No README data
npm http GET https://registry.npmjs.org/grunt
npm http 304 https://registry.npmjs.org/grunt
npm http GET https://registry.npmjs.org/colors
npm http GET https://registry.npmjs.org/dateformat/1.0.2-1.2.3
npm http GET https://registry.npmjs.org/eventemitter2
npm http GET https://registry.npmjs.org/findup-sync
npm http GET https://registry.npmjs.org/glob
npm http GET https://registry.npmjs.org/hooker
npm http GET https://registry.npmjs.org/iconv-lite
npm http GET https://registry.npmjs.org/minimatch
npm http GET https://registry.npmjs.org/nopt
npm http GET https://registry.npmjs.org/rimraf
npm http GET https://registry.npmjs.org/lodash
npm http GET https://registry.npmjs.org/which
npm http GET https://registry.npmjs.org/underscore.string
npm http GET https://registry.npmjs.org/js-yaml
npm http GET https://registry.npmjs.org/exit
npm http GET https://registry.npmjs.org/grunt-legacy-util
npm http GET https://registry.npmjs.org/getobject
npm http GET https://registry.npmjs.org/async
npm http GET https://registry.npmjs.org/coffee-script
npm http 304 https://registry.npmjs.org/glob
npm http 304 https://registry.npmjs.org/hooker
npm http 304 https://registry.npmjs.org/eventemitter2
npm http 304 https://registry.npmjs.org/minimatch
npm http 304 https://registry.npmjs.org/nopt
npm http 304 https://registry.npmjs.org/colors
npm http 304 https://registry.npmjs.org/dateformat/1.0.2-1.2.3
npm http 304 https://registry.npmjs.org/findup-sync
npm http 304 https://registry.npmjs.org/iconv-lite
npm http 304 https://registry.npmjs.org/lodash
npm http 304 https://registry.npmjs.org/which
npm http 304 https://registry.npmjs.org/rimraf
npm http 304 https://registry.npmjs.org/underscore.string
npm http 304 https://registry.npmjs.org/grunt-legacy-util
npm http 304 https://registry.npmjs.org/js-yaml
npm http 304 https://registry.npmjs.org/exit
npm http 304 https://registry.npmjs.org/async
npm http 304 https://registry.npmjs.org/getobject
npm http 304 https://registry.npmjs.org/coffee-script
npm http GET https://registry.npmjs.org/abbrev
npm http GET https://registry.npmjs.org/lru-cache
npm http GET https://registry.npmjs.org/sigmund
npm http 304 https://registry.npmjs.org/abbrev
npm http GET https://registry.npmjs.org/graceful-fs
npm http GET https://registry.npmjs.org/inherits
npm http 304 https://registry.npmjs.org/sigmund
npm http 304 https://registry.npmjs.org/lru-cache
npm http GET https://registry.npmjs.org/argparse
npm http GET https://registry.npmjs.org/esprima
npm http 304 https://registry.npmjs.org/graceful-fs
npm http GET https://registry.npmjs.org/inherits
npm http 304 https://registry.npmjs.org/inherits
npm http 304 https://registry.npmjs.org/inherits
npm http 304 https://registry.npmjs.org/argparse
npm http 304 https://registry.npmjs.org/esprima
npm http GET https://registry.npmjs.org/underscore
npm http 304 https://registry.npmjs.org/underscore
[email protected] node_modules/grunt
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected] ([email protected])
├── [email protected]
├── [email protected]
├── [email protected] ([email protected], [email protected])
├── [email protected]
├── [email protected] ([email protected], [email protected])
├── [email protected]
├── [email protected] ([email protected], [email protected])
└── [email protected] ([email protected], [email protected])
~~~

grunt-contrib-jshintというGruntがJSHintを実行するのに必要なものも入れましょう

~~~
$ npm install grunt-contrib-jshint –save-dev
npm WARN package.json [email protected] No description
npm WARN package.json [email protected] No README data
npm http GET https://registry.npmjs.org/grunt-contrib-jshint
npm http 304 https://registry.npmjs.org/grunt-contrib-jshint
npm http GET https://registry.npmjs.org/hooker
npm http GET https://registry.npmjs.org/jshint
npm http 304 https://registry.npmjs.org/hooker
npm http 304 https://registry.npmjs.org/jshint
npm http GET https://registry.npmjs.org/underscore
npm http GET https://registry.npmjs.org/minimatch
npm http GET https://registry.npmjs.org/exit
npm http GET https://registry.npmjs.org/cli
npm http GET https://registry.npmjs.org/shelljs
npm http GET https://registry.npmjs.org/htmlparser2
npm http GET https://registry.npmjs.org/console-browserify
npm http GET https://registry.npmjs.org/strip-json-comments
npm http 304 https://registry.npmjs.org/minimatch
npm http 304 https://registry.npmjs.org/exit
npm http 304 https://registry.npmjs.org/underscore
npm http 304 https://registry.npmjs.org/htmlparser2
npm http 304 https://registry.npmjs.org/cli
npm http 304 https://registry.npmjs.org/console-browserify
npm http 304 https://registry.npmjs.org/strip-json-comments
npm http 304 https://registry.npmjs.org/shelljs
npm http GET https://registry.npmjs.org/lru-cache
npm http GET https://registry.npmjs.org/sigmund
npm http GET https://registry.npmjs.org/glob
npm http 304 https://registry.npmjs.org/glob
npm http 304 https://registry.npmjs.org/lru-cache
npm http GET https://registry.npmjs.org/inherits
npm http 304 https://registry.npmjs.org/sigmund
npm http GET https://registry.npmjs.org/domelementtype
npm http GET https://registry.npmjs.org/domhandler
npm http GET https://registry.npmjs.org/domutils
npm http GET https://registry.npmjs.org/readable-stream
npm http 304 https://registry.npmjs.org/inherits
npm http 304 https://registry.npmjs.org/readable-stream
npm http 304 https://registry.npmjs.org/domutils
npm http 304 https://registry.npmjs.org/domhandler
npm http 304 https://registry.npmjs.org/domelementtype
npm http GET https://registry.npmjs.org/core-util-is
npm http GET https://registry.npmjs.org/isarray/0.0.1
npm http GET https://registry.npmjs.org/string_decoder
npm http 304 https://registry.npmjs.org/core-util-is
npm http 304 https://registry.npmjs.org/isarray/0.0.1
npm http 304 https://registry.npmjs.org/string_decoder
[email protected] node_modules/grunt-contrib-jshint
├── [email protected]
└── [email protected] (strip-json-co[email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected])
~~~

さらにGruntfile.jsというプロジェクトをビルドする際のタスクの設定・振舞いを記載するファイルを作らないといけません
これは自動で作ってくれる機能がないようなので?手で作ります
~~~
module.exports = function (grunt) {
grunt.initConfig({
jshint: {
options: {
node: true
},
files: {
src: [ ‘Gruntfile.js’ ]
}
}
});

grunt.loadNpmTasks(‘grunt-contrib-jshint’);
grunt.registerTask(‘default’, [ ‘jshint’ ]);
};
~~~

さてGruntを実行してみましょう。。

~~~
$ grunt
Running “jshint:files” (jshint) task
>> 1 file lint free.

Done, without errors.
~~~

実行できたようです。
EC-CUBE固有のjsもGruntfile.jsに追加してみます

~~~
module.exports = function (grunt) {
grunt.initConfig({
jshint: {
options: {
node: true,
maxerr: 200,
browser: true,
devel: true,
unused: true
},
files: {
src: [
‘Gruntfile.js’,
‘html/js/eccube.js’,
‘html/user_data/packages/admin/js/breadcrumbs.js’,
‘html/user_data/packages/admin/js/eccube.admin.js’,
‘html/user_data/packages/admin/js/layout_design.js ‘,
‘html/user_data/packages/sphone/js/eccube.sphone.js’,
]
}
}
});
grunt.loadNpmTasks(‘grunt-contrib-jshint’);
grunt.registerTask(‘default’, [ ‘jshint’ ]);
};

~~~

実行してみて動いているようなのでとりあえずこれでいいのかな?
~~~
>> 88 errors in 6 files
Warning: Task “jshint:files” failed. Use –force to continue.

Aborted due to warnings.
~~~

Travis CIに対応させる

やっと本題にたどり着いた感じです。。。
さてEC-CUBEはすでにPHP用の.travis.ymlを作ってあるのでこれに追記してJSHintも実行させてみます

.travis.ymlにnpm installなどを追加
~~~
# for travis-ci
# see also. https://travis-ci.org
language: php

php:
– 5.5
– 5.4
– 5.3

env:
– DB=mysql USER=root DBNAME=myapp_test DBPASS=’ ‘ DBUSER=root
– DB=pgsql USER=postgres DBNAME=myapp_test DBPASS=password DBUSER=postgres

before_script:
– curl -s http://getcomposer.org/installer | php
– php composer.phar install –dev –no-interaction
– sh -c “if [ ‘$DB’ = ‘mysql’ ]; then mysql -e ‘CREATE DATABASE myapp_test;’; fi”
– sh -c “if [ ‘$DB’ = ‘mysql’ ]; then sh ./eccube_install.sh mysql; fi”
– sh -c “if [ ‘$DB’ = ‘pgsql’ ]; then psql -c ‘create database myapp_test;’ -U postgres; fi”
– sh -c “if [ ‘$DB’ = ‘pgsql’ ]; then sh ./eccube_install.sh pgsql; fi”
– cp tests/require.php.jenkins tests/require.php
– cat ./data/config/config.php
– npm install -g grunt-cli
– npm install

script:
– mkdir -p reports/coverage
– phpunit –log-tap reports/tap.log –log-junit reports/unitreport.xml –coverage-html reports/coverage –coverage-clover reports/coverage/coverage.xml –bootstrap ./data/config/config.php –configuration tests/phpunit.xml.jenkins tests
– grunt

after_script:
– php vendor/bin/coveralls -v

~~~

6パターンをテストしているのに、そこに追加するしかないというのがちょっと残念ですがlanguageは増やせないみたいなのでしょうがない。。

あとはpackege.jsonも修正します
~~~

“scripts”: {
“test”: “grunt test” // ここだけ修正
},

~~~

これでpushすれば・・・
Travis CI – Free Hosted Continuous Integration Platform for the Open Source Community

出来ました!
ただこれだとテストが落ちていることになっちゃうのが難点ですねぇ・・
なにか良い方法があれば教えて欲しいです

参考サイト

JSHint Options Reference
GRUNT とJSHintのコードチェックをビルドプロセスに組み込む – Gaishimo
かずぽんブログ • GruntをスクラッチなJavascriptプロジェクトに導入する