diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 0000000000..bbe03ddda6 --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,83 @@ +var webpack = require('webpack'); +var webpackConfig = require('./webpack.dev.config'); +webpackConfig.devtool = 'inline-source-map'; + +// Karma configuration +// Generated on Thu Oct 01 2015 08:45:20 GMT-0700 (PDT) + +module.exports = function(config) { + config.set({ + + // base path that will be used to resolve all patterns (eg. files, exclude) + basePath: '', + + + // frameworks to use + // available frameworks: https://npmjs.org/browse/keyword/karma-adapter + frameworks: ['mocha', 'chai-sinon'], + + + // list of files / patterns to load in the browser + files: [ + 'tests/fixtures/phantomjs-shims.js', + 'tests/tests_bundle.js' + ], + + + // list of files to exclude + exclude: [ + ], + + + // preprocess matching files before serving them to the browser + // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor + preprocessors: { + 'tests/tests_bundle.js': ['webpack','sourcemap'] + }, + + + // test results reporter to use + // possible values: 'dots', 'progress' + // available reporters: https://npmjs.org/browse/keyword/karma-reporter + 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: 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, + + webpack : webpackConfig, + + + plugins: [ + require('karma-webpack'), + require('karma-mocha'), + require('karma-chai-sinon'), + require('karma-sourcemap-loader'), + require('karma-phantomjs-launcher'), + require('karma-chrome-launcher') + ] + }) +} diff --git a/package.json b/package.json index 529bd97420..ddada65482 100644 --- a/package.json +++ b/package.json @@ -32,22 +32,36 @@ "main": "lib/index.js", "homepage": "https://github.com/salesforce-ux/design-system-react", "devDependencies": { + "babel": "^5.8.23", "babel-core": "^5.4.7", "babel-eslint": "^3.1.9", "babel-loader": "^5.1.2", - "babel": "^5.8.23", + "chai": "^3.3.0", "css-loader": "^0.9.1", "eslint-plugin-react": "^2.3.0", "extract-text-webpack-plugin": "^0.8.2", "file-loader": "^0.8.4", + "karma": "^0.13.10", + "karma-chai-sinon": "^0.1.5", + "karma-chrome-launcher": "^0.2.0", + "karma-cli": "^0.1.1", + "karma-mocha": "^0.2.0", + "karma-phantomjs-launcher": "^0.2.1", + "karma-sourcemap-loader": "^0.3.5", + "karma-webpack": "^1.7.0", + "mocha": "^2.3.3", + "phantomjs": "^1.9.18", "raw-loader": "^0.5.1", + "react": "^0.13.0", "react-hot-loader": "^1.2.7", + "react-prism": "^1.4.1", + "react-router": "^0.13.3", + "sinon": "^1.17.1", + "sinon-chai": "^2.8.0", "style-loader": "^0.9.0", "url-loader": "^0.5.6", "webpack": "^1.9.6", - "webpack-dev-server": "^1.8.2", - "react-prism": "^1.4.1", - "react-router": "^0.13.3" + "webpack-dev-server": "^1.8.2" }, "dependencies": { "classnames": "^2.1.3", @@ -56,8 +70,5 @@ "react-onclickoutside": "^0.3.0", "tether": "^1.1.0", "tether-drop": "^1.2.2" - }, - "peerDependencies": { - "react": "^0.13.0" } } diff --git a/tests/SLDSPicklistBase/picklistBase.test.jsx b/tests/SLDSPicklistBase/picklistBase.test.jsx new file mode 100644 index 0000000000..696728a1dc --- /dev/null +++ b/tests/SLDSPicklistBase/picklistBase.test.jsx @@ -0,0 +1,35 @@ +const React = require('react/addons'); +const TestUtils = React.addons.TestUtils; +import {SLDSPicklistBase} from '../../components'; + +describe('SLDSPicklistBase: ', function(){ + + let clickOnItem = (cmp, index) => { + let items = TestUtils.scryRenderedDOMComponentsWithTag( + cmp, 'a' + ); + + TestUtils.Simulate.click(items[index]); + }; + + it('onSelect fires upon selection change', sinon.test(function() { + let onSelectStub = this.stub(); + let options = [ + {"value" : '1', "label" : '1'} + ]; + + let cmp = TestUtils.renderIntoDocument( + + ); + + let button = TestUtils.findRenderedDOMComponentWithTag( + cmp, 'button' + ); + + TestUtils.Simulate.click(button); + clickOnItem(cmp, 0); + + expect(onSelectStub.calledOnce).to.be.ok; + expect(onSelectStub.calledWith('1')).to.be.ok; + })); +}); diff --git a/tests/fixtures/phantomjs-shims.js b/tests/fixtures/phantomjs-shims.js new file mode 100644 index 0000000000..3b4c0ff5dd --- /dev/null +++ b/tests/fixtures/phantomjs-shims.js @@ -0,0 +1,36 @@ +(function() { + //Src: https://gist.github.com/noradaiko/12cbaf8a1674e3b8c8e6 + +var Ap = Array.prototype; +var slice = Ap.slice; +var Fp = Function.prototype; + +if (!Fp.bind) { + // PhantomJS doesn't support Function.prototype.bind natively, so + // polyfill it whenever this module is required. + Fp.bind = function(context) { + var func = this; + var args = slice.call(arguments, 1); + + function bound() { + var invokedAsConstructor = func.prototype && (this instanceof func); + return func.apply( + // Ignore the context parameter when invoking the bound function + // as a constructor. Note that this includes not only constructor + // invocations using the new keyword but also calls to base class + // constructors such as BaseClass.call(this, ...) or super(...). + !invokedAsConstructor && context || this, + args.concat(slice.call(arguments)) + ); + } + + // The bound function must share the .prototype of the unbound + // function so that any object created by one constructor will count + // as an instance of both constructors. + bound.prototype = func.prototype; + + return bound; + }; +} + +})(); diff --git a/tests/tests_bundle.js b/tests/tests_bundle.js new file mode 100644 index 0000000000..52c887785d --- /dev/null +++ b/tests/tests_bundle.js @@ -0,0 +1,6 @@ +// tests/tests_bundle.js + +// require all modules ending in ".test.js" or ".test.jsx" from the +// current directory and all subdirectories +var testsContext = require.context(".", true, /.test.(js|jsx)$/); +testsContext.keys().forEach(testsContext); diff --git a/webpack.dev.config.js b/webpack.dev.config.js index a7fff9bfd6..2639a56c31 100644 --- a/webpack.dev.config.js +++ b/webpack.dev.config.js @@ -33,6 +33,11 @@ module.exports = { loaders: ['react-hot', 'babel'], include: [path.join(__dirname, 'demo'),path.join(__dirname, 'components')] }, + { + test: /\.(js|jsx)?$/, + loaders: ['react-hot', 'babel'], + include: [path.join(__dirname, 'tests')] + }, { test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader")