Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests, docs, build #266

Draft
wants to merge 59 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
aa2d926
Account for file created by yarn install in gitignore
TNick Oct 12, 2023
924966d
Merge remote-tracking branch 'upstream/master'
TNick Oct 13, 2023
fe556a4
Merge branch 'master' of https://github.com/qgis/qwc2
TNick Oct 13, 2023
2859428
Initial configuration for building a library, tests and documentation
TNick Oct 14, 2023
1008a4d
Tests for all functions in CoordinatesUtils
TNick Oct 15, 2023
76fbe43
rimraf is dev dependency
TNick Oct 15, 2023
b65ed8a
Document some actions and store components
TNick Oct 15, 2023
810a01f
Add typescript
TNick Oct 15, 2023
baae1e0
Move to typedoc
TNick Oct 15, 2023
7c26543
Add some definitions (store-related), integrate them into source file…
TNick Oct 15, 2023
8592688
Add documentation and types for measurement-related code
TNick Oct 16, 2023
6925f02
Measurement utils test
TNick Oct 17, 2023
01b9727
Locale utils tests and docs
TNick Oct 17, 2023
6852ca7
map utils tests
TNick Oct 18, 2023
00e7314
Merge branch 'master' of https://github.com/qgis/qwc2 into add_tests_…
TNick Oct 18, 2023
742792a
Misc utils tests
TNick Oct 18, 2023
7460fce
Forgot some comments in source code
TNick Oct 18, 2023
84d046d
Signal tests
TNick Oct 19, 2023
a9cbfe8
distinct setup files (global and after-env)
TNick Oct 20, 2023
36ba6d9
ConfigUtils tests
TNick Oct 20, 2023
b27ec1b
properly exclude test files from typescript compilation
TNick Oct 21, 2023
33e71af
Editing interface tests
TNick Oct 21, 2023
76329b3
Added feature styles tests
TNick Oct 21, 2023
7b4f59b
Add test stubs. Format code in utils
TNick Oct 22, 2023
952b272
VectorLayerUtils tests
TNick Oct 22, 2023
180c509
Theme utils tests
TNick Oct 22, 2023
dd6a72d
image editor test
TNick Oct 22, 2023
62fdafe
A permalink test
TNick Oct 22, 2023
b735dfd
layers utils - partial
TNick Oct 24, 2023
0f76965
Merged master changes
TNick Oct 24, 2023
54a3b6c
use import instead of require in scripts
TNick Oct 24, 2023
c0fcbbd
Silence console warnings (arrays should be objects)
TNick Oct 24, 2023
84435f3
More layer tests. Changed name to id in implodeLayers
TNick Oct 26, 2023
8a49f28
Integrate upstream changes
TNick Oct 26, 2023
3f7f477
insertLayer and implodeLayers tests
TNick Oct 26, 2023
dae0f1e
Improve insertLayer docs
TNick Oct 26, 2023
623eb45
layerScaleInRange tests
TNick Oct 26, 2023
76e9afa
setGroupVisibilities tests
TNick Oct 26, 2023
186758b
WMS layers and friends
TNick Oct 27, 2023
90ed544
buildWMSLayerUrlParam tests
TNick Oct 27, 2023
a12510e
splitLayerUrlParam tests
TNick Oct 27, 2023
acb8dac
Introducing vscode settings (for ignored words in spell checker)
TNick Oct 28, 2023
d48798f
removeLayer tests
TNick Oct 28, 2023
ef9ea56
reorderLayer tests
TNick Oct 28, 2023
484d596
insertPermalinkLayers tests
TNick Oct 28, 2023
0eb674b
restoreLayerParams tests
TNick Oct 28, 2023
328bbb4
collectPrintParams - partial tests
TNick Oct 28, 2023
1474899
only compare visibility with false, as true and undefined means visible
TNick Oct 28, 2023
71e6cac
addExternalLayerPrintParams tests
TNick Oct 28, 2023
0837f28
completeExternalLayer tests
TNick Oct 28, 2023
3dae9f9
getLegendUrl tests
TNick Oct 28, 2023
cefb440
getSublayerNames tests
TNick Oct 28, 2023
2950d5b
mergeSubLayers tests
TNick Oct 28, 2023
fdde6ae
searchSubLayer tests
TNick Oct 28, 2023
325210d
searchLayer tests
TNick Oct 28, 2023
5b37956
getAttribution tests
TNick Oct 28, 2023
3ce872b
getTimeDimensionValues tests
TNick Oct 28, 2023
ca15471
restoreOrderedLayerParams tests
TNick Oct 28, 2023
7a52ecd
Fix tests for setGroupVisibilities
TNick Oct 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"rules": {},
"env": {
"es6": true,
"browser": true
},
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"plugins": [
"react"
]
}
17 changes: 16 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
node_modules/
npm-debug.log

# On a fresh install with yarn 3.3.0 these extra files were generated.
.yarn
.pnp.cjs
.pnp.loader.mjs
yarn.lock

documentation/
.cache/
coverage/
dist/*
dist-dev/*
*.log

# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
17 changes: 17 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"cSpell.words": [
"bbox",
"EPSG",
"extwmsparams",
"isempty",
"isequal",
"maxx",
"maxy",
"miny",
"reproject",
"reprojecting",
"Sublayer",
"sublayers",
"USERLAYER"
]
}
1 change: 1 addition & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodeLinker: node-modules
51 changes: 51 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,54 @@ See:
* [this presentation](https://blog.sourcepole.ch/assets/2019/qwc2-foss4g19.pdf) for an overview and architecture of QWC2.

Please report QWC2 issues at [qwc2-demo-app/issues](https://github.com/qgis/qwc2-demo-app/issues).

Development
-----------

Start by installing the development dependencies:

yarn install

All the output generated by the commands below is deposited directly
in the root directory of the repository. To clean up the output:

yarn clean

### Building

We use webpack to build the QWC2 library. Check out its configuration
in `webpack.config.js`.

To build the library in production mode:

yarn build-prod

To build the library in development mode:

yarn build-dev

The results are deposited in `dist/` for production
and `dist-dev/` for development.

### Testing

We use Jest to run unit tests. It is configured in `jest.config.js`
and coverage data is collected in `coverage/`.

The tests can be run with:

yarn test

To run the tests in watch mode:

yarn test-watch

### Documentation

We use TypeDoc to document the QWC2 library. It is configured in `typedoc.json`
and the resulting documentation is deposited in `documentation/`.

JsDoc documentation can be generated with one of the following commands:

yarn doc
yarn doc --watch
2 changes: 2 additions & 0 deletions __mocks__/axios.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import mockAxios from 'jest-mock-axios';
export default mockAxios;
1 change: 1 addition & 0 deletions __mocks__/fileMock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 'test-file-stub';
1 change: 1 addition & 0 deletions __mocks__/styleMock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default {};
8 changes: 7 additions & 1 deletion actions/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@ ReducerIndex.register("browser", browserReducer);

export const CHANGE_BROWSER_PROPERTIES = 'CHANGE_BROWSER_PROPERTIES';


/**
* Update browser properties.
*
* @param {import("qwc2/typings").BrowserData} properties - information
* retrieved by {@link ConfigUtils.getBrowserProperties}.
* @group Redux Store.Actions
*/
export function changeBrowserProperties(properties) {
return {
type: CHANGE_BROWSER_PROPERTIES,
Expand Down
16 changes: 16 additions & 0 deletions actions/display.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ ReducerIndex.register("display", displayReducer);

export const TOGGLE_FULLSCREEN = 'TOGGLE_FULLSCREEN';

/**
* Issues a request to the browser to
* enter full screen mode.
*/
export function requestFullscreen() {
if (document.documentElement.requestFullscreen) {
document.documentElement.requestFullscreen();
Expand All @@ -24,6 +28,10 @@ export function requestFullscreen() {
}
}

/**
* Issues a request to the browser to
* exit full screen mode.
*/
export function endFullscreen() {
if (document.exitFullscreen) {
document.exitFullscreen();
Expand All @@ -36,6 +44,14 @@ export function endFullscreen() {
}
}


/**
* Change full screen mode.
*
* @param {boolean} fullscreen - true to enter full
* screen mode, false to exit it.
* @group Redux Store.Actions
*/
export function toggleFullscreen(fullscreen) {
if (fullscreen) {
requestFullscreen();
Expand Down
85 changes: 85 additions & 0 deletions actions/editing.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@ ReducerIndex.register("editing", editingReducer);
export const SET_EDIT_CONTEXT = 'SET_EDIT_CONTEXT';
export const CLEAR_EDIT_CONTEXT = 'CLEAR_EDIT_CONTEXT';


/**
* Set current edit context.
*
* The `contextId` is set in the store as the `currentContext` and the
* `editContext` is saved into the context identified
* by the `contextId` in the store's `contexts` members.
*
* @param {string} contextId - the ID of this context.
* @param {object} editContext - the context.
* @group Redux Store.Actions
*/
export function setEditContext(contextId, editContext) {
return {
type: SET_EDIT_CONTEXT,
Expand All @@ -21,6 +33,18 @@ export function setEditContext(contextId, editContext) {
};
}


/**
* Clear current edit context.
*
* The context identified by the `contextId` is removed from the store's
* `contexts` members and the `newActiveContextId` is set as the new
* `currentContext` (but only if `contextId` is currently `currentContext`).
*
* @param {string} contextId - the ID of this context.
* @param {object} newActiveContextId - the context.
* @group Redux Store.Actions
*/
export function clearEditContext(contextId, newActiveContextId = null) {
return {
type: CLEAR_EDIT_CONTEXT,
Expand All @@ -29,12 +53,55 @@ export function clearEditContext(contextId, newActiveContextId = null) {
};
}


// This is where we keep the feature template factories
// for each dataset. It maps dataset names to functions
// that transform a feature in `getFeatureTemplate()`.
const FeatureTemplateFactories = {};

/**
* @callback FeatureTemplate
*
* The factory function takes a feature as input and
* returns a feature as output. The feature is then
* used as the template for the feature form.
*
* @param {object} feature - the input feature
* @returns {object} the output feature
*/


/**
* Set the feature template factory for a dataset.
*
* The factory function takes a feature as input and
* returns a feature as output. The feature is then
* used as the template for the feature form.
*
* @param {string} dataset - the dataset name.
* @param {FeatureTemplate} factory - the factory function.
*/
export function setFeatureTemplateFactory(dataset, factory) {
FeatureTemplateFactories[dataset] = factory;
}

/**
* Compute a defaukt value for a field.
*
* The default value is evaluated as follows:
* - if it starts with `expr:` then the rest of the
* string is evaluated as follows:
* - `expr:now()` returns the current date/time
* - `expr:true` returns `true`
* - `expr:false` returns `false`
* - otherwise it returns an empty string.
* - otherwise the string is used as is.
*
* @param {object} field - the field to evaluate
*
* @returns {any} the default value
* @private
*/
function evaluateDefaultValue(field) {
if (field.defaultValue.startsWith("expr:")) {
const expr = field.defaultValue.slice(5);
Expand All @@ -55,6 +122,24 @@ function evaluateDefaultValue(field) {
}
}


/**
* Get a feature template for a dataset.
*
* The feature template is computed as follows:
* - if the dataset has a feature template factory
* registered, then the factory is called with the
* feature as input and the result is then used in next step;
* - each field of the feature is checked for a
* `defaultValue` property and if it exists, the
* default value is evaluated and assigned to the
* feature's `properties` attribute under the `id` of the field.
*
* @param {object} editConfig - the edit configuration
* @param {object} feature - the input feature
*
* @returns {object} the output feature
*/
export function getFeatureTemplate(editConfig, feature) {
if (editConfig.editDataset in FeatureTemplateFactories) {
feature = FeatureTemplateFactories[editConfig.editDataset](feature);
Expand Down
25 changes: 23 additions & 2 deletions actions/identify.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,31 @@ import ConfigUtils from '../utils/ConfigUtils';

export const SET_IDENTIFY_TOOL = 'SET_IDENTIFY_TOOL';


/**
* Sets the current identify tool.
*
* The function will use the `identifyTool` property from the
* `theme` argument or from current theme if `theme` is not specified.
*
* If the theme does not specify an `identifyTool` property,
* the default `Identify` is used.
*
* If the `enabled` argument is `false`, the current tool is set to `null`.
*
* @param {boolean} enabled - whether identify tool is enabled.
* @param {string} theme - optional theme name to use for identify tool.
*
* @group Redux Store.Actions
*/
export function setIdentifyEnabled(enabled, theme = null) {
return (dispatch, getState) => {
let identifyTool = ConfigUtils.getConfigProp("identifyTool", theme || getState().theme.current);
identifyTool = identifyTool !== undefined ? identifyTool : "Identify";
let identifyTool = ConfigUtils.getConfigProp(
"identifyTool", theme || getState().theme.current
);
identifyTool = identifyTool !== undefined
? identifyTool
: "Identify";
dispatch({
type: SET_IDENTIFY_TOOL,
tool: enabled ? identifyTool : null
Expand Down
Loading