kopia lustrzana https://github.com/OpenDroneMap/WebODM
ModelView frontend tests, moved jquery-i18next, updated docs, jest config
rodzic
040bf0b96b
commit
c3dc4244b5
|
@ -1,14 +1,15 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
import Map from '../Map';
|
import Map from '../Map';
|
||||||
|
import sinon from 'sinon';
|
||||||
|
|
||||||
|
sinon.useFakeXMLHttpRequest();
|
||||||
|
|
||||||
describe('<Map />', () => {
|
describe('<Map />', () => {
|
||||||
it('renders without exploding', () => {
|
it('renders without exploding', () => {
|
||||||
const wrapper = shallow(<Map
|
const wrapper = mount(<Map
|
||||||
tiles={['/tiles.json']} />);
|
tiles={['/tiles.json']} />);
|
||||||
|
|
||||||
// TODO: componentDidUpdate method is never called
|
|
||||||
|
|
||||||
expect(wrapper.exists()).toBe(true);
|
expect(wrapper.exists()).toBe(true);
|
||||||
})
|
})
|
||||||
});
|
});
|
|
@ -1,15 +1,13 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
import ProjectListItem from '../ProjectListItem';
|
import ProjectListItem from '../ProjectListItem';
|
||||||
|
import createHistory from 'history/createBrowserHistory';
|
||||||
const projectMock = require('../../tests/utils/MockLoader').load("project.json");
|
const projectMock = require('../../tests/utils/MockLoader').load("project.json");
|
||||||
|
|
||||||
describe('<ProjectListItem />', () => {
|
describe('<ProjectListItem />', () => {
|
||||||
it('renders without exploding', () => {
|
it('renders without exploding', () => {
|
||||||
// TODO: load history mock
|
|
||||||
|
|
||||||
const wrapper = shallow(<ProjectListItem
|
const wrapper = shallow(<ProjectListItem
|
||||||
history={window.history}
|
history={createHistory()}
|
||||||
data={projectMock} />);
|
data={projectMock} />);
|
||||||
expect(wrapper.exists()).toBe(true);
|
expect(wrapper.exists()).toBe(true);
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
import TaskListItem from '../TaskListItem';
|
import TaskListItem from '../TaskListItem';
|
||||||
|
import createHistory from 'history/createBrowserHistory';
|
||||||
const taskMock = require('../../tests/utils/MockLoader').load("task.json");
|
const taskMock = require('../../tests/utils/MockLoader').load("task.json");
|
||||||
|
|
||||||
describe('<TaskListItem />', () => {
|
describe('<TaskListItem />', () => {
|
||||||
it('renders without exploding', () => {
|
it('renders without exploding', () => {
|
||||||
// TODO: load history mock
|
const wrapper = shallow(<TaskListItem history={createHistory()} data={taskMock} />);
|
||||||
const wrapper = shallow(<TaskListItem history={{}} data={taskMock} />);
|
|
||||||
expect(wrapper.exists()).toBe(true);
|
expect(wrapper.exists()).toBe(true);
|
||||||
})
|
})
|
||||||
});
|
});
|
|
@ -1,13 +1,11 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
// import ModelView from '../ModelView';
|
import ModelView from '../ModelView';
|
||||||
|
const taskMock = require('./utils/MockLoader').load("task.json");
|
||||||
// TODO: this needs some debugging since Potree has troubles with requirements
|
|
||||||
|
|
||||||
describe('<ModelView />', () => {
|
describe('<ModelView />', () => {
|
||||||
it('TODO: renders without exploding', () => {
|
it('renders without exploding', () => {
|
||||||
expect(true).toBe(true);
|
const wrapper = shallow(<ModelView task={taskMock} />);
|
||||||
// const wrapper = shallow(<ModelView task={{id: 1, project: 1}} />);
|
expect(wrapper.exists()).toBe(true);
|
||||||
// expect(wrapper.exists()).toBe(true);
|
|
||||||
})
|
})
|
||||||
});
|
});
|
|
@ -0,0 +1,9 @@
|
||||||
|
// Define certain DOM elements
|
||||||
|
// that are not defined in the JEST environment
|
||||||
|
|
||||||
|
const currentScript = document.createElement('script');
|
||||||
|
currentScript.src = "http://bogus";
|
||||||
|
|
||||||
|
Object.defineProperty(document, 'currentScript', {
|
||||||
|
value: currentScript
|
||||||
|
});
|
|
@ -0,0 +1,117 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
tName: 't',
|
||||||
|
i18nName: 'i18n',
|
||||||
|
handleName: 'localize',
|
||||||
|
selectorAttr: 'data-i18n',
|
||||||
|
targetAttr: 'i18n-target',
|
||||||
|
optionsAttr: 'i18n-options',
|
||||||
|
useOptionsAttr: false,
|
||||||
|
parseDefaultValueFromContent: true
|
||||||
|
};
|
||||||
|
|
||||||
|
function init(i18next, $) {
|
||||||
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
||||||
|
|
||||||
|
|
||||||
|
options = _extends({}, defaults, options);
|
||||||
|
|
||||||
|
function parse(ele, key, opts) {
|
||||||
|
if (key.length === 0) return;
|
||||||
|
|
||||||
|
var attr = 'text';
|
||||||
|
|
||||||
|
if (key.indexOf('[') === 0) {
|
||||||
|
var parts = key.split(']');
|
||||||
|
key = parts[1];
|
||||||
|
attr = parts[0].substr(1, parts[0].length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key.indexOf(';') === key.length - 1) {
|
||||||
|
key = key.substr(0, key.length - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function extendDefault(o, val) {
|
||||||
|
if (!options.parseDefaultValueFromContent) return o;
|
||||||
|
return _extends({}, o, { defaultValue: val });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attr === 'html') {
|
||||||
|
ele.html(i18next.t(key, extendDefault(opts, ele.html())));
|
||||||
|
} else if (attr === 'text') {
|
||||||
|
ele.text(i18next.t(key, extendDefault(opts, ele.text())));
|
||||||
|
} else if (attr === 'prepend') {
|
||||||
|
ele.prepend(i18next.t(key, extendDefault(opts, ele.html())));
|
||||||
|
} else if (attr === 'append') {
|
||||||
|
ele.append(i18next.t(key, extendDefault(opts, ele.html())));
|
||||||
|
} else if (attr.indexOf('data-') === 0) {
|
||||||
|
var dataAttr = attr.substr('data-'.length);
|
||||||
|
var translated = i18next.t(key, extendDefault(opts, ele.data(dataAttr)));
|
||||||
|
|
||||||
|
// we change into the data cache
|
||||||
|
ele.data(dataAttr, translated);
|
||||||
|
// we change into the dom
|
||||||
|
ele.attr(attr, translated);
|
||||||
|
} else {
|
||||||
|
ele.attr(attr, i18next.t(key, extendDefault(opts, ele.attr(attr))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function localize(ele, opts) {
|
||||||
|
var key = ele.attr(options.selectorAttr);
|
||||||
|
if (!key && typeof key !== 'undefined' && key !== false) key = ele.text() || ele.val();
|
||||||
|
if (!key) return;
|
||||||
|
|
||||||
|
var target = ele,
|
||||||
|
targetSelector = ele.data(options.targetAttr);
|
||||||
|
|
||||||
|
if (targetSelector) target = ele.find(targetSelector) || ele;
|
||||||
|
|
||||||
|
if (!opts && options.useOptionsAttr === true) opts = ele.data(options.optionsAttr);
|
||||||
|
|
||||||
|
opts = opts || {};
|
||||||
|
|
||||||
|
if (key.indexOf(';') >= 0) {
|
||||||
|
var keys = key.split(';');
|
||||||
|
|
||||||
|
$.each(keys, function (m, k) {
|
||||||
|
if (k !== '') parse(target, k, opts);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
parse(target, key, opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.useOptionsAttr === true) {
|
||||||
|
var clone = {};
|
||||||
|
clone = _extends({ clone: clone }, opts);
|
||||||
|
|
||||||
|
delete clone.lng;
|
||||||
|
ele.data(options.optionsAttr, clone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle(opts) {
|
||||||
|
return this.each(function () {
|
||||||
|
// localize element itself
|
||||||
|
localize($(this), opts);
|
||||||
|
|
||||||
|
// localize children
|
||||||
|
var elements = $(this).find('[' + options.selectorAttr + ']');
|
||||||
|
elements.each(function () {
|
||||||
|
localize($(this), opts);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// $.t $.i18n shortcut
|
||||||
|
$[options.tName] = i18next.t.bind(i18next);
|
||||||
|
$[options.i18nName] = i18next;
|
||||||
|
|
||||||
|
// selector function $(mySelector).localize(opts);
|
||||||
|
$.fn[options.handleName] = handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = init;
|
|
@ -6,10 +6,10 @@ import proj4 from 'proj4';
|
||||||
import TWEEN from 'tween.js';
|
import TWEEN from 'tween.js';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import i18n from './i18next';
|
import i18n from './i18next';
|
||||||
import jqueryi18n from 'jquery-i18next';
|
import jqueryi18n from './jquery-i18next';
|
||||||
import d3 from 'd3';
|
import d3 from 'd3';
|
||||||
|
|
||||||
jqueryi18n.init(i18n, $, {
|
jqueryi18n(i18n, $, {
|
||||||
tName: 't', // --> appends $.t = i18next.t
|
tName: 't', // --> appends $.t = i18next.t
|
||||||
i18nName: 'i18n', // --> appends $.i18n = i18next
|
i18nName: 'i18n', // --> appends $.i18n = i18next
|
||||||
handleName: 'i18n', // --> appends $(selector).localize(opts);
|
handleName: 'i18n', // --> appends $(selector).localize(opts);
|
||||||
|
|
|
@ -12,7 +12,7 @@ usage(){
|
||||||
echo "Command list:"
|
echo "Command list:"
|
||||||
echo " start Start the development environment"
|
echo " start Start the development environment"
|
||||||
echo " stop Stop the development environment"
|
echo " stop Stop the development environment"
|
||||||
echo " runtests [tests] Run unit tests. You can specify an optional extra parameter such as app.tests.test_db to limit the scope of the tests. Defaults to running all tests."
|
echo " runtests Run unit tests"
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ stop(){
|
||||||
}
|
}
|
||||||
|
|
||||||
runtests(){
|
runtests(){
|
||||||
run "docker-compose exec webapp python manage.py test $1"
|
run "docker-compose exec webapp /bin/bash -c \"/webodm/webodm.sh test\""
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ $1 = "start" ]]; then
|
if [[ $1 = "start" ]]; then
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
roots: ["./app/static/app/js"],
|
roots: ["./app/static/app/js"],
|
||||||
"moduleNameMapper": {
|
moduleNameMapper: {
|
||||||
"^.*\\.s?css$": "<rootDir>/app/static/app/js/tests/mocks/empty.scss.js",
|
"^.*\\.s?css$": "<rootDir>/app/static/app/js/tests/mocks/empty.scss.js",
|
||||||
"jquery": "<rootDir>/app/static/app/js/vendor/jquery-1.11.2.min.js"
|
"jquery": "<rootDir>/app/static/app/js/vendor/jquery-1.11.2.min.js"
|
||||||
}
|
},
|
||||||
|
setupFiles: ["<rootDir>/app/static/app/js/tests/setup/browserMock.js"]
|
||||||
};
|
};
|
|
@ -4,7 +4,8 @@
|
||||||
"description": "Open Source Drone Image Processing",
|
"description": "Open Source Drone Image Processing",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "jest"
|
"test": "python manage.py test app.tests.test_generate_ui_mocks && jest",
|
||||||
|
"qtest": "jest"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -36,7 +37,6 @@
|
||||||
"gl-matrix": "^2.3.2",
|
"gl-matrix": "^2.3.2",
|
||||||
"immutability-helper": "^2.0.0",
|
"immutability-helper": "^2.0.0",
|
||||||
"jest": "^21.0.1",
|
"jest": "^21.0.1",
|
||||||
"jquery-i18next": "^1.2.0",
|
|
||||||
"json-loader": "^0.5.4",
|
"json-loader": "^0.5.4",
|
||||||
"leaflet": "^1.0.1",
|
"leaflet": "^1.0.1",
|
||||||
"leaflet-measure": "^2.0.5",
|
"leaflet-measure": "^2.0.5",
|
||||||
|
@ -52,6 +52,7 @@
|
||||||
"react-test-renderer": "^15.6.1",
|
"react-test-renderer": "^15.6.1",
|
||||||
"regenerator-runtime": "^0.11.0",
|
"regenerator-runtime": "^0.11.0",
|
||||||
"sass-loader": "^4.0.2",
|
"sass-loader": "^4.0.2",
|
||||||
|
"sinon": "^4.0.0",
|
||||||
"statuses": "^1.3.1",
|
"statuses": "^1.3.1",
|
||||||
"style-loader": "^0.13.1",
|
"style-loader": "^0.13.1",
|
||||||
"tween.js": "^16.6.0",
|
"tween.js": "^16.6.0",
|
||||||
|
|
|
@ -32,7 +32,7 @@ If you can follow the instructions to [run WebODM natively](https://github.com/O
|
||||||
|
|
||||||
## Run Unit Tests
|
## Run Unit Tests
|
||||||
|
|
||||||
We think testing is a necessary part of delivering robust software. We try to achieve complete test coverage for backend code, while we are more relaxed about frontend testing. See [#119](https://github.com/OpenDroneMap/WebODM/issues/119).
|
We think testing is a necessary part of delivering robust software. We try to achieve complete test coverage for backend code and at a minimum robust smoke testing for frontend code.
|
||||||
|
|
||||||
To run the unit tests, simply type:
|
To run the unit tests, simply type:
|
||||||
|
|
||||||
|
|
14
webodm.sh
14
webodm.sh
|
@ -28,6 +28,7 @@ usage(){
|
||||||
echo " update Update WebODM to the latest release"
|
echo " update Update WebODM to the latest release"
|
||||||
echo " rebuild Rebuild all docker containers and perform cleanups"
|
echo " rebuild Rebuild all docker containers and perform cleanups"
|
||||||
echo " checkenv Do an environment check and install missing components"
|
echo " checkenv Do an environment check and install missing components"
|
||||||
|
echo " test Run the unit test suite (developers only)"
|
||||||
echo " resetadminpassword <newpassword> Reset the administrator's password to a new one. WebODM must be running when executing this command."
|
echo " resetadminpassword <newpassword> Reset the administrator's password to a new one. WebODM must be running when executing this command."
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
@ -85,6 +86,17 @@ rebuild(){
|
||||||
echo -e "\033[1mDone!\033[0m You can now start WebODM by running $0 start"
|
echo -e "\033[1mDone!\033[0m You can now start WebODM by running $0 start"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
run_tests(){
|
||||||
|
echo -e "\033[1mRunning frontend tests\033[0m"
|
||||||
|
run "npm run test"
|
||||||
|
|
||||||
|
echo "\033[1mRunning backend tests\033[0m"
|
||||||
|
run "python manage.py test"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo -e "\033[1mDone!\033[0m Everything looks in order."
|
||||||
|
}
|
||||||
|
|
||||||
resetpassword(){
|
resetpassword(){
|
||||||
newpass=$1
|
newpass=$1
|
||||||
|
|
||||||
|
@ -132,6 +144,8 @@ elif [[ $1 = "update" ]]; then
|
||||||
echo -e "\033[1mDone!\033[0m You can now start WebODM by running $0 start"
|
echo -e "\033[1mDone!\033[0m You can now start WebODM by running $0 start"
|
||||||
elif [[ $1 = "checkenv" ]]; then
|
elif [[ $1 = "checkenv" ]]; then
|
||||||
environment_check
|
environment_check
|
||||||
|
elif [[ $1 = "test" ]]; then
|
||||||
|
run_tests
|
||||||
elif [[ $1 = "resetadminpassword" ]]; then
|
elif [[ $1 = "resetadminpassword" ]]; then
|
||||||
resetpassword $2
|
resetpassword $2
|
||||||
else
|
else
|
||||||
|
|
Ładowanie…
Reference in New Issue