Merge pull request #264 from matrix-org/rav/react_testing_tweaks
Improvements to the react-sdk test framework
This commit is contained in:
commit
5f96e9980b
6 changed files with 75 additions and 27 deletions
|
@ -11,11 +11,18 @@ var fs = require('fs');
|
||||||
* If you run karma in multi-run mode (with `npm run test-multi`), it will watch
|
* 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
|
* the tests for changes, and webpack will rebuild using a cache. This is much quicker
|
||||||
* than a clean rebuild.
|
* than a clean rebuild.
|
||||||
*
|
|
||||||
* TODO:
|
|
||||||
* - can we run one test at a time?
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// the name of the test file. By default, a special file which runs all tests.
|
||||||
|
//
|
||||||
|
// TODO: this could be a pattern, and karma would run each file, with a
|
||||||
|
// separate webpack bundle for each file. But then we get a separate instance
|
||||||
|
// of the sdk, and each of the dependencies, for each test file, and everything
|
||||||
|
// gets very confused. Can we persuade webpack to put all of the dependencies
|
||||||
|
// in a 'common' bundle?
|
||||||
|
//
|
||||||
|
var testFile = process.env.KARMA_TEST_FILE || 'test/all-tests.js';
|
||||||
|
|
||||||
process.env.PHANTOMJS_BIN = 'node_modules/.bin/phantomjs';
|
process.env.PHANTOMJS_BIN = 'node_modules/.bin/phantomjs';
|
||||||
|
|
||||||
function fileExists(name) {
|
function fileExists(name) {
|
||||||
|
@ -33,6 +40,7 @@ if (!fileExists(gsCss)) {
|
||||||
gsCss = 'node_modules/react-gemini-scrollbar/'+gsCss;
|
gsCss = 'node_modules/react-gemini-scrollbar/'+gsCss;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
module.exports = function (config) {
|
module.exports = function (config) {
|
||||||
config.set({
|
config.set({
|
||||||
// frameworks to use
|
// frameworks to use
|
||||||
|
@ -41,15 +49,15 @@ module.exports = function (config) {
|
||||||
|
|
||||||
// list of files / patterns to load in the browser
|
// list of files / patterns to load in the browser
|
||||||
files: [
|
files: [
|
||||||
'test/tests.js',
|
testFile,
|
||||||
gsCss,
|
gsCss,
|
||||||
],
|
],
|
||||||
|
|
||||||
// list of files to exclude
|
// list of files to exclude
|
||||||
//
|
//
|
||||||
// This doesn't work. It turns out that it's webpack which does the
|
// This doesn't work. It turns out that it's webpack which does the
|
||||||
// watching of the /test directory (possibly karma only watches
|
// watching of the /test directory (karma only watches `testFile`
|
||||||
// tests.js itself). Webpack watches the directory so that it can spot
|
// itself). Webpack watches the directory so that it can spot
|
||||||
// new tests, which is fair enough; unfortunately it triggers a rebuild
|
// new tests, which is fair enough; unfortunately it triggers a rebuild
|
||||||
// every time a lockfile is created in that directory, and there
|
// every time a lockfile is created in that directory, and there
|
||||||
// doesn't seem to be any way to tell webpack to ignore particular
|
// doesn't seem to be any way to tell webpack to ignore particular
|
||||||
|
@ -63,7 +71,7 @@ module.exports = function (config) {
|
||||||
// available preprocessors:
|
// available preprocessors:
|
||||||
// https://npmjs.org/browse/keyword/karma-preprocessor
|
// https://npmjs.org/browse/keyword/karma-preprocessor
|
||||||
preprocessors: {
|
preprocessors: {
|
||||||
'test/tests.js': ['webpack', 'sourcemap']
|
'test/**/*.js': ['webpack', 'sourcemap']
|
||||||
},
|
},
|
||||||
|
|
||||||
// test results reporter to use
|
// test results reporter to use
|
||||||
|
@ -139,7 +147,7 @@ module.exports = function (config) {
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'matrix-react-sdk': path.resolve('src/index.js'),
|
'matrix-react-sdk': path.resolve('test/skinned-sdk.js'),
|
||||||
'sinon': 'sinon/pkg/sinon.js',
|
'sinon': 'sinon/pkg/sinon.js',
|
||||||
},
|
},
|
||||||
root: [
|
root: [
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
// tests.js
|
// all-tests.js
|
||||||
//
|
//
|
||||||
// Our master test file: uses the webpack require API to find our test files
|
// Our master test file: uses the webpack require API to find our test files
|
||||||
// and run them
|
// and run them
|
||||||
|
|
||||||
// this is a handly place to make sure the sdk has been skinned
|
|
||||||
var sdk = require("matrix-react-sdk");
|
|
||||||
sdk.loadSkin(require('./test-component-index'));
|
|
||||||
|
|
||||||
var context = require.context('.', true, /-test\.jsx?$/);
|
var context = require.context('.', true, /-test\.jsx?$/);
|
||||||
context.keys().forEach(context);
|
context.keys().forEach(context);
|
|
@ -3,16 +3,21 @@ var TestUtils = require('react-addons-test-utils');
|
||||||
var expect = require('expect');
|
var expect = require('expect');
|
||||||
|
|
||||||
var sdk = require('matrix-react-sdk');
|
var sdk = require('matrix-react-sdk');
|
||||||
|
var MatrixChat = sdk.getComponent('structures.MatrixChat');
|
||||||
|
var peg = require('../../../src/MatrixClientPeg');
|
||||||
|
|
||||||
var test_utils = require('../../test-utils');
|
var test_utils = require('../../test-utils');
|
||||||
var peg = require('../../../src/MatrixClientPeg.js');
|
|
||||||
var q = require('q');
|
var q = require('q');
|
||||||
|
|
||||||
describe('MatrixChat', function () {
|
describe('MatrixChat', function () {
|
||||||
var MatrixChat;
|
var sandbox;
|
||||||
before(function() {
|
|
||||||
test_utils.stubClient();
|
beforeEach(function() {
|
||||||
MatrixChat = sdk.getComponent('structures.MatrixChat');
|
sandbox = test_utils.stubClient();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function() {
|
||||||
|
sandbox.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('gives a login panel by default', function () {
|
it('gives a login panel by default', function () {
|
||||||
|
|
|
@ -27,12 +27,19 @@ var test_utils = require('test-utils');
|
||||||
var mockclock = require('mock-clock');
|
var mockclock = require('mock-clock');
|
||||||
|
|
||||||
describe('MessagePanel', function () {
|
describe('MessagePanel', function () {
|
||||||
|
var sandbox;
|
||||||
var clock = mockclock.clock();
|
var clock = mockclock.clock();
|
||||||
var realSetTimeout = window.setTimeout;
|
var realSetTimeout = window.setTimeout;
|
||||||
var events = mkEvents();
|
var events = mkEvents();
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
test_utils.beforeEach(this);
|
||||||
|
sandbox = test_utils.stubClient(sandbox);
|
||||||
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
clock.uninstall();
|
clock.uninstall();
|
||||||
|
sandbox.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
function mkEvents() {
|
function mkEvents() {
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
/*
|
/*
|
||||||
* test-component-index.js
|
* skinned-sdk.js
|
||||||
*
|
*
|
||||||
* Stub out a bunch of the components which we expect the application to
|
* Skins the react-sdk with a few stub components which we expect the
|
||||||
* provide
|
* application to provide
|
||||||
*/
|
*/
|
||||||
var components = require('../src/component-index.js').components;
|
|
||||||
|
var sdk = require("../src/index");
|
||||||
|
|
||||||
|
var skin = require('../src/component-index.js');
|
||||||
var stubComponent = require('./components/stub-component.js');
|
var stubComponent = require('./components/stub-component.js');
|
||||||
|
|
||||||
|
var components = skin.components;
|
||||||
components['structures.LeftPanel'] = stubComponent();
|
components['structures.LeftPanel'] = stubComponent();
|
||||||
components['structures.RightPanel'] = stubComponent();
|
components['structures.RightPanel'] = stubComponent();
|
||||||
components['structures.RoomDirectory'] = stubComponent();
|
components['structures.RoomDirectory'] = stubComponent();
|
||||||
|
@ -18,4 +22,6 @@ components['views.messages.DateSeparator'] = stubComponent({displayName: 'DateSe
|
||||||
components['views.messages.MessageTimestamp'] = stubComponent({displayName: 'MessageTimestamp'});
|
components['views.messages.MessageTimestamp'] = stubComponent({displayName: 'MessageTimestamp'});
|
||||||
components['views.messages.SenderProfile'] = stubComponent({displayName: 'SenderProfile'});
|
components['views.messages.SenderProfile'] = stubComponent({displayName: 'SenderProfile'});
|
||||||
|
|
||||||
module.exports.components = components;
|
sdk.loadSkin(skin);
|
||||||
|
|
||||||
|
module.exports = sdk;
|
|
@ -1,9 +1,11 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
var sinon = require('sinon');
|
||||||
|
var q = require('q');
|
||||||
|
|
||||||
var peg = require('../src/MatrixClientPeg.js');
|
var peg = require('../src/MatrixClientPeg.js');
|
||||||
var jssdk = require('matrix-js-sdk');
|
var jssdk = require('matrix-js-sdk');
|
||||||
var MatrixEvent = jssdk.MatrixEvent;
|
var MatrixEvent = jssdk.MatrixEvent;
|
||||||
var sinon = require('sinon');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform common actions before each test case, e.g. printing the test case
|
* Perform common actions before each test case, e.g. printing the test case
|
||||||
|
@ -21,12 +23,36 @@ module.exports.beforeEach = function(context) {
|
||||||
/**
|
/**
|
||||||
* Stub out the MatrixClient, and configure the MatrixClientPeg object to
|
* Stub out the MatrixClient, and configure the MatrixClientPeg object to
|
||||||
* return it when get() is called.
|
* return it when get() is called.
|
||||||
|
*
|
||||||
|
* @returns {sinon.Sandbox}; remember to call sandbox.restore afterwards.
|
||||||
*/
|
*/
|
||||||
module.exports.stubClient = function() {
|
module.exports.stubClient = function() {
|
||||||
var pegstub = sinon.stub(peg);
|
var sandbox = sinon.sandbox.create();
|
||||||
|
|
||||||
var matrixClientStub = sinon.createStubInstance(jssdk.MatrixClient);
|
var client = {
|
||||||
pegstub.get.returns(matrixClientStub);
|
getHomeserverUrl: sinon.stub(),
|
||||||
|
getIdentityServerUrl: sinon.stub(),
|
||||||
|
|
||||||
|
getPushActionsForEvent: sinon.stub(),
|
||||||
|
getRoom: sinon.stub(),
|
||||||
|
loginFlows: sinon.stub(),
|
||||||
|
on: sinon.stub(),
|
||||||
|
|
||||||
|
paginateEventTimeline: sinon.stub().returns(q()),
|
||||||
|
sendReadReceipt: sinon.stub().returns(q()),
|
||||||
|
};
|
||||||
|
|
||||||
|
// create the peg
|
||||||
|
|
||||||
|
// 'sandbox.restore()' doesn't work correctly on inherited methods,
|
||||||
|
// so we do this for each method
|
||||||
|
var methods = ['get', 'unset', 'replaceUsingUrls',
|
||||||
|
'replaceUsingAccessToken'];
|
||||||
|
for (var i = 0; i < methods.length; i++) {
|
||||||
|
sandbox.stub(peg, methods[i]);
|
||||||
|
}
|
||||||
|
peg.get.returns(client);
|
||||||
|
return sandbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue