diff --git a/.gitignore b/.gitignore index 2bc43f864a..df91879d0d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,9 @@ -node_modules -vector/bundle.* -lib -.DS_Store -key.pem -cert.pem -vector/components.css -packages/ +/cert.pem +/.DS_Store +/karma-reports +/key.pem +/lib +/node_modules +/packages/ +/vector/bundle.* +/vector/components.css diff --git a/jenkins.sh b/jenkins.sh index 634703eb29..f60bec38b2 100755 --- a/jenkins.sh +++ b/jenkins.sh @@ -13,8 +13,11 @@ npm install # we may be using a dev branch of react-sdk, in which case we need to build it (cd node_modules/matrix-react-sdk && npm run build) +# run the mocha tests +npm run test + # build our artifacts; dumps them in ./vector -npm run build +npm run build:dev # gzip up ./vector rm vector-*.tar.gz || true # rm previous artifacts without failing if it doesn't exist diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 0000000000..b97273796b --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,136 @@ +// karma.conf.js - the config file for karma, which runs our tests. + +var path = require('path'); +var webpack = require('webpack'); + +/* + * We use webpack to build our tests. It's a pain to have to wait for webpack + * to build everything; however it's the easiest way to load our dependencies + * from node_modules. + * + * If you run karma in multi-run mode (with `npm run test:multi`), it will watch + * the tests for changes, and webpack will rebuild using a cache. This is much quicker + * than a clean rebuild. + */ + +// the name of the test file. By default, a special file which runs all tests. +var testFile = process.env.KARMA_TEST_FILE || 'test/all-tests.js'; + +process.env.PHANTOMJS_BIN = 'node_modules/.bin/phantomjs'; +process.env.Q_DEBUG = 1; + +module.exports = function (config) { + config.set({ + // frameworks to use + // available frameworks: https://npmjs.org/browse/keyword/karma-adapter + frameworks: ['mocha'], + + // list of files / patterns to load in the browser + files: [ + testFile, + {pattern: 'vector/img/*', watched: false, included: false, served: true, nocache: false}, + ], + + // redirect img links to the karma server + proxies: { + "/img/": "/base/vector/img/", + }, + + // preprocess matching files before serving them to the browser + // available preprocessors: + // https://npmjs.org/browse/keyword/karma-preprocessor + preprocessors: { + 'test/**/*.js': ['webpack', 'sourcemap'] + }, + + // test results reporter to use + // possible values: 'dots', 'progress' + // available reporters: https://npmjs.org/browse/keyword/karma-reporter + reporters: ['progress', 'junit'], + + // 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: true, + + // start these browsers + // available browser launchers: + // https://npmjs.org/browse/keyword/karma-launcher + browsers: [ + 'Chrome', + //'PhantomJS', + ], + + // Continuous Integration mode + // if true, Karma captures browsers, runs the tests and exits + // singleRun: false, + + // Concurrency level + // how many browser should be started simultaneous + concurrency: Infinity, + + junitReporter: { + outputDir: 'karma-reports', + }, + + webpack: { + module: { + loaders: [ + { test: /\.json$/, loader: "json" }, + { + test: /\.js$/, loader: "babel", + include: [path.resolve('./src'), + path.resolve('./test'), + ], + query: { + // we're using babel 5, for consistency with + // the release build, which doesn't use the + // presets. + // presets: ['react', 'es2015'], + }, + }, + ], + noParse: [ + // don't parse the languages within highlight.js. They + // cause stack overflows + // (https://github.com/webpack/webpack/issues/1721), and + // there is no need for webpack to parse them - they can + // just be included as-is. + /highlight\.js\/lib\/languages/, + + // also disable parsing for sinon, because it + // tries to do voodoo with 'require' which upsets + // webpack (https://github.com/webpack/webpack/issues/304) + /sinon\/pkg\/sinon\.js$/, + ], + }, + resolve: { + alias: { + // alias any requires to the react module to the one in our path, otherwise + // we tend to get the react source included twice when using npm link. + react: path.resolve('./node_modules/react'), + + // same goes for js-sdk + "matrix-js-sdk": path.resolve('./node_modules/matrix-js-sdk'), + + sinon: 'sinon/pkg/sinon.js', + }, + root: [ + path.resolve('./src'), + path.resolve('./test'), + ], + }, + devtool: 'inline-source-map', + }, + }); +}; diff --git a/package.json b/package.json index 223672b8d8..6c85f552e2 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,9 @@ "build:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/components.css --no-watch", "build:compile": "babel --source-maps -d lib src", "build:bundle": "NODE_ENV=production webpack -p lib/vector/index.js vector/bundle.js", + "build:bundle:dev": "webpack --optimize-occurence-order lib/vector/index.js vector/bundle.js", "build": "npm run build:css && npm run build:compile && npm run build:bundle", + "build:dev": "npm run build:css && npm run build:compile && npm run build:bundle:dev", "package": "scripts/package.sh", "start:js": "webpack -w src/vector/index.js vector/bundle.js", "start:js:prod": "NODE_ENV=production webpack -w src/vector/index.js vector/bundle.js", @@ -25,7 +27,9 @@ "start": "parallelshell \"npm run start:js\" \"npm run start:skins:css\" \"http-server -c 1 vector\"", "start:prod": "parallelshell \"npm run start:js:prod\" \"npm run start:skins:css\" \"http-server -c 1 vector\"", "clean": "rimraf lib vector/bundle.css vector/bundle.js vector/bundle.js.map vector/webpack.css*", - "prepublish": "npm run build:css && npm run build:compile" + "prepublish": "npm run build:css && npm run build:compile", + "test": "karma start --single-run=true --autoWatch=false --browsers PhantomJS --colors=false", + "test:multi": "karma start" }, "dependencies": { "babel-polyfill": "^6.5.0", @@ -41,7 +45,7 @@ "matrix-react-sdk": "matrix-org/matrix-react-sdk#develop", "modernizr": "^3.1.0", "q": "^1.4.1", - "react": "^0.14.2", + "react": "^0.14.8", "react-dnd": "^2.0.2", "react-dnd-html5-backend": "^2.0.0", "react-dom": "^0.14.2", @@ -54,11 +58,23 @@ "babel-loader": "^5.3.2", "catw": "^1.0.1", "css-raw-loader": "^0.1.1", + "expect": "^1.16.0", "http-server": "^0.8.4", "json-loader": "^0.5.3", + "karma": "^0.13.22", + "karma-chrome-launcher": "^0.2.3", + "karma-cli": "^0.1.2", + "karma-junit-reporter": "^0.4.1", + "karma-mocha": "^0.2.2", + "karma-phantomjs-launcher": "^1.0.0", + "karma-sourcemap-loader": "^0.3.7", + "karma-webpack": "^1.7.0", + "mocha": "^2.4.5", "parallelshell": "^1.2.0", + "phantomjs-prebuilt": "^2.1.7", + "react-addons-test-utils": "^0.14.8", "rimraf": "^2.4.3", "source-map-loader": "^0.1.5", - "webpack": "^1.12.13" + "webpack": "^1.12.14" } } diff --git a/src/components/structures/LeftPanel.js b/src/components/structures/LeftPanel.js index 0e13f39e4a..5c27abc58e 100644 --- a/src/components/structures/LeftPanel.js +++ b/src/components/structures/LeftPanel.js @@ -89,7 +89,7 @@ var LeftPanel = React.createClass({ var BottomLeftMenu = sdk.getComponent('structures.BottomLeftMenu'); var collapseButton; - var classes = "mx_LeftPanel"; + var classes = "mx_LeftPanel mx_fadable"; if (this.props.collapsed) { classes += " collapsed"; } @@ -109,7 +109,7 @@ var LeftPanel = React.createClass({ } return ( -