@kbss-cvut/s-forms 0.4.1 → 0.4.2-alpha-8c711c4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/MediaContent.d.ts +3 -13
- package/dist/s-forms.cjs +1 -1
- package/dist/s-forms.cjs.map +1 -1
- package/dist/s-forms.js +1 -1
- package/dist/s-forms.js.map +1 -1
- package/dist/s-forms.modern.js +1 -1
- package/dist/s-forms.modern.js.map +1 -1
- package/dist/s-forms.umd.js +1 -1
- package/dist/s-forms.umd.js.map +1 -1
- package/package.json +14 -2
- package/.babelrc +0 -22
- package/.github/workflows/check-format.yml +0 -21
- package/.github/workflows/chromatic.yml +0 -24
- package/.husky/pre-commit +0 -4
- package/.prettierignore +0 -4
- package/.storybook/main.cjs +0 -11
- package/.storybook/preview.js +0 -103
- package/dist/stories/MediaContent.stories.d.ts +0 -5
- package/jest.config.cjs +0 -20
- package/test/__mocks__/styleMock.js +0 -1
- package/test/__tests__/Answer.test.js +0 -399
- package/test/__tests__/DefaultFormGenerator.test.js +0 -34
- package/test/__tests__/FormUtils.test.js +0 -297
- package/test/__tests__/InputAnswer.test.js +0 -193
- package/test/__tests__/JsonLdFramingUtils.test.js +0 -29
- package/test/__tests__/JsonLdObjectUtils.test.js +0 -86
- package/test/__tests__/MaskMapper.test.js +0 -32
- package/test/__tests__/MaskedInputAnswer.test.js +0 -90
- package/test/__tests__/Question.test.js +0 -102
- package/test/__tests__/QuestionAnswerProcessor.test.js +0 -183
- package/test/__tests__/QuestionCommentIcon.test.js +0 -77
- package/test/__tests__/TypeheadAnswer.test.js +0 -102
- package/test/environment/Generator.js +0 -44
- package/test/setup.js +0 -19
- package/tsconfig.json +0 -20
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kbss-cvut/s-forms",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2-alpha-8c711c4.0",
|
|
4
4
|
"description": "Semantic forms generator and processor",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"type": "module",
|
|
38
38
|
"source": "src/s-forms.js",
|
|
39
|
+
"main": "dist/s-forms.js",
|
|
39
40
|
"exports": "./dist/s-forms.modern.js",
|
|
40
41
|
"module": "./dist/s-forms.js",
|
|
41
42
|
"unpkg": "./dist/s-forms.umd.js",
|
|
@@ -71,7 +72,6 @@
|
|
|
71
72
|
"react-bootstrap": "1.0.1",
|
|
72
73
|
"react-dom": ">= 17.0.2"
|
|
73
74
|
},
|
|
74
|
-
"main": "dist/s-forms.js",
|
|
75
75
|
"devDependencies": {
|
|
76
76
|
"@storybook/addon-a11y": "^6.4.19",
|
|
77
77
|
"@storybook/addon-actions": "^6.4.19",
|
|
@@ -94,6 +94,7 @@
|
|
|
94
94
|
"query-string": "^6.13.5",
|
|
95
95
|
"react": "~17.0.2",
|
|
96
96
|
"react-dom": "~17.0.2",
|
|
97
|
+
"standard-version": "^9.3.2",
|
|
97
98
|
"style-loader": "^1.2.1",
|
|
98
99
|
"typescript": "^4.5.5",
|
|
99
100
|
"watchify": "^3.11.1",
|
|
@@ -105,9 +106,20 @@
|
|
|
105
106
|
"build": "microbundle --jsx React.createElement",
|
|
106
107
|
"build-storybook": "build-storybook",
|
|
107
108
|
"chromatic": "npx chromatic",
|
|
109
|
+
"release:patch": "npm test && standard-version --release-as patch && npm publish",
|
|
110
|
+
"release:major": "npm test && standard-version --release-as major && npm publish",
|
|
111
|
+
"release:minor": "npm test && standard-version --release-as minor && npm publish",
|
|
108
112
|
"prettier:check": "npx prettier --check .",
|
|
109
113
|
"prettier:format": "npx prettier --write .",
|
|
110
114
|
"prepare": "husky install"
|
|
111
115
|
},
|
|
116
|
+
"standard-version": {
|
|
117
|
+
"releaseCommitMessageFormat": "[{{currentTag}}] Bump version"
|
|
118
|
+
},
|
|
119
|
+
"files": [
|
|
120
|
+
"dist/",
|
|
121
|
+
"css/",
|
|
122
|
+
"types/"
|
|
123
|
+
],
|
|
112
124
|
"types": "./dist/s-forms.d.ts"
|
|
113
125
|
}
|
package/.babelrc
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"presets": [
|
|
3
|
-
"@babel/preset-typescript",
|
|
4
|
-
[
|
|
5
|
-
"@babel/preset-env",
|
|
6
|
-
{
|
|
7
|
-
"modules": false,
|
|
8
|
-
"useBuiltIns": "usage",
|
|
9
|
-
"corejs": {
|
|
10
|
-
"version": 3,
|
|
11
|
-
"proposals": true
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
],
|
|
15
|
-
"@babel/preset-react"
|
|
16
|
-
],
|
|
17
|
-
"env": {
|
|
18
|
-
"test": {
|
|
19
|
-
"presets": ["@babel/preset-env", "@babel/preset-react"]
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
name: Check code format
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
- "*"
|
|
7
|
-
|
|
8
|
-
jobs:
|
|
9
|
-
check-format:
|
|
10
|
-
runs-on: ubuntu-latest
|
|
11
|
-
steps:
|
|
12
|
-
- uses: actions/checkout@v2
|
|
13
|
-
with:
|
|
14
|
-
fetch-depth: 0
|
|
15
|
-
|
|
16
|
-
- uses: actions/setup-node@v2
|
|
17
|
-
with:
|
|
18
|
-
node-version: 16
|
|
19
|
-
registry-url: https://registry.npmjs.org
|
|
20
|
-
- run: npm ci
|
|
21
|
-
- run: npm run prettier:check
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# Workflow name
|
|
2
|
-
name: "Chromatic"
|
|
3
|
-
|
|
4
|
-
# Event for the workflow
|
|
5
|
-
on: push
|
|
6
|
-
|
|
7
|
-
# List of jobs
|
|
8
|
-
jobs:
|
|
9
|
-
chromatic-deployment:
|
|
10
|
-
# Operating System
|
|
11
|
-
runs-on: ubuntu-latest
|
|
12
|
-
# Job steps
|
|
13
|
-
steps:
|
|
14
|
-
- uses: actions/checkout@v1
|
|
15
|
-
- name: Install dependencies
|
|
16
|
-
run: npm install
|
|
17
|
-
# 👇 Adds Chromatic as a step in the workflow
|
|
18
|
-
- name: Publish to Chromatic
|
|
19
|
-
uses: chromaui/action@v1
|
|
20
|
-
# Chromatic GitHub Action options
|
|
21
|
-
with:
|
|
22
|
-
# 👇 Chromatic projectToken, refer to the manage page to obtain it.
|
|
23
|
-
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
|
24
|
-
exitZeroOnChanges: true # 👈 Option to prevent the workflow from failing
|
package/.husky/pre-commit
DELETED
package/.prettierignore
DELETED
package/.storybook/main.cjs
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
|
|
3
|
-
addons: [
|
|
4
|
-
"@storybook/addon-links",
|
|
5
|
-
"@storybook/addon-essentials",
|
|
6
|
-
"@storybook/addon-interactions",
|
|
7
|
-
"@luigiminardim/storybook-addon-globals-controls",
|
|
8
|
-
"@storybook/addon-a11y",
|
|
9
|
-
],
|
|
10
|
-
framework: "@storybook/react",
|
|
11
|
-
};
|
package/.storybook/preview.js
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import Constants from "../src/constants/Constants";
|
|
2
|
-
import { addDecorator } from "@storybook/react";
|
|
3
|
-
import IntlContextProvider from "../src/contexts/IntlContextProvider";
|
|
4
|
-
import { FormGenContextProvider } from "../src/contexts/FormGenContext";
|
|
5
|
-
import { ConfigurationContextProvider } from "../src/contexts/ConfigurationContext";
|
|
6
|
-
|
|
7
|
-
import "react-datepicker/dist/react-datepicker.css";
|
|
8
|
-
import "bootstrap/dist/css/bootstrap.min.css";
|
|
9
|
-
import "../src/styles/s-forms.css";
|
|
10
|
-
import possibleValues from "../src/stories/assets/possibleValues.json";
|
|
11
|
-
|
|
12
|
-
export const parameters = {
|
|
13
|
-
actions: { argTypesRegex: "^on[A-Z].*" },
|
|
14
|
-
controls: {
|
|
15
|
-
matchers: {
|
|
16
|
-
color: /(background|color)$/i,
|
|
17
|
-
date: /Date$/,
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export const globalTypes = {
|
|
23
|
-
iconBehavior: {
|
|
24
|
-
name: "Icon behavior",
|
|
25
|
-
description: "Set the behavior for the icons",
|
|
26
|
-
defaultValue: Constants.ICON_BEHAVIOR.ON_HOVER,
|
|
27
|
-
options: [
|
|
28
|
-
Constants.ICON_BEHAVIOR.ON_HOVER,
|
|
29
|
-
Constants.ICON_BEHAVIOR.ENABLE,
|
|
30
|
-
Constants.ICON_BEHAVIOR.DISABLE,
|
|
31
|
-
],
|
|
32
|
-
control: { type: "radio" },
|
|
33
|
-
},
|
|
34
|
-
locale: {
|
|
35
|
-
name: "Locale",
|
|
36
|
-
description: "Internationalization locale",
|
|
37
|
-
defaultValue: "en",
|
|
38
|
-
options: ["en", "cs"],
|
|
39
|
-
control: { type: "radio" },
|
|
40
|
-
},
|
|
41
|
-
debugMode: {
|
|
42
|
-
name: "Debug Mode",
|
|
43
|
-
description: "Show irrelevant questions",
|
|
44
|
-
defaultValue: false,
|
|
45
|
-
control: { type: "boolean" },
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const options = {
|
|
50
|
-
i18n: {
|
|
51
|
-
"wizard.next": "Next",
|
|
52
|
-
"wizard.previous": "Previous",
|
|
53
|
-
"section.expand": "Expand",
|
|
54
|
-
"section.collapse": "Collapse",
|
|
55
|
-
},
|
|
56
|
-
intl: {
|
|
57
|
-
locale: "en",
|
|
58
|
-
},
|
|
59
|
-
modalView: false,
|
|
60
|
-
horizontalWizardNav: false,
|
|
61
|
-
wizardStepButtons: true,
|
|
62
|
-
enableForwardSkip: true,
|
|
63
|
-
startingStep: 1,
|
|
64
|
-
debugMode: false,
|
|
65
|
-
users: [
|
|
66
|
-
{ id: "http://fel.cvut.cz/people/max-chopart", label: "Max Chopart" },
|
|
67
|
-
{
|
|
68
|
-
id: "http://fel.cvut.cz/people/miroslav-blasko",
|
|
69
|
-
label: "Miroslav Blasko",
|
|
70
|
-
},
|
|
71
|
-
],
|
|
72
|
-
currentUser: "http://fel.cvut.cz/people/max-chopart",
|
|
73
|
-
icons: [
|
|
74
|
-
{
|
|
75
|
-
id: Constants.ICONS.QUESTION_HELP,
|
|
76
|
-
behavior: Constants.ICON_BEHAVIOR.ENABLE,
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
id: Constants.ICONS.QUESTION_LINK,
|
|
80
|
-
behavior: Constants.ICON_BEHAVIOR.ENABLE,
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
id: Constants.ICONS.QUESTION_COMMENTS,
|
|
84
|
-
behavior: Constants.ICON_BEHAVIOR.ENABLE,
|
|
85
|
-
},
|
|
86
|
-
],
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
const fetchTypeAheadValues = () => {
|
|
90
|
-
return new Promise((resolve) =>
|
|
91
|
-
setTimeout(() => resolve(possibleValues), 1500)
|
|
92
|
-
);
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
addDecorator((story) => (
|
|
96
|
-
<ConfigurationContextProvider options={options}>
|
|
97
|
-
<FormGenContextProvider fetchTypeAheadValues={fetchTypeAheadValues}>
|
|
98
|
-
<IntlContextProvider locale={globalTypes.locale.defaultValue}>
|
|
99
|
-
{story()}
|
|
100
|
-
</IntlContextProvider>
|
|
101
|
-
</FormGenContextProvider>
|
|
102
|
-
</ConfigurationContextProvider>
|
|
103
|
-
));
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import MediaContent from "../components/MediaContent";
|
|
2
|
-
import { ComponentMeta, ComponentStory } from "@storybook/react";
|
|
3
|
-
declare const _default: ComponentMeta<typeof MediaContent>;
|
|
4
|
-
export default _default;
|
|
5
|
-
export declare const Default: ComponentStory<typeof MediaContent>;
|
package/jest.config.cjs
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
roots: ["<rootDir>"],
|
|
3
|
-
moduleFileExtensions: ["js", "jsx", "json", "ts", "tsx"],
|
|
4
|
-
setupFiles: ["<rootDir>/test/setup.js"],
|
|
5
|
-
transformIgnorePatterns: ["[/\\\\]node_modules[/\\\\].+\\.(ts|tsx)$"],
|
|
6
|
-
testEnvironment: "jsdom",
|
|
7
|
-
testURL: "http://localhost",
|
|
8
|
-
transform: {
|
|
9
|
-
"^.+\\.(js|jsx|ts|tsx)$": "babel-jest",
|
|
10
|
-
},
|
|
11
|
-
reporters: ["default"],
|
|
12
|
-
moduleNameMapper: {
|
|
13
|
-
"\\.(css)$": "<rootDir>/test/__mocks__/styleMock.js",
|
|
14
|
-
},
|
|
15
|
-
globals: {
|
|
16
|
-
"s-forms": {
|
|
17
|
-
tsconfig: "tsconfig.spec.json",
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = {};
|
|
@@ -1,399 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { format } from "date-fns";
|
|
3
|
-
import DatePicker from "react-datepicker";
|
|
4
|
-
import Select from "react-select";
|
|
5
|
-
|
|
6
|
-
import * as Generator from "../environment/Generator";
|
|
7
|
-
import Answer from "../../src/components/Answer";
|
|
8
|
-
import Constants from "../../src/constants/Constants";
|
|
9
|
-
import TypeaheadAnswer from "../../src/components/answer/TypeaheadAnswer";
|
|
10
|
-
import MaskedInput from "../../src/components/MaskedInput";
|
|
11
|
-
import { FormGenContext } from "../../src/contexts/FormGenContext";
|
|
12
|
-
import { ConfigurationContext } from "../../src/contexts/ConfigurationContext";
|
|
13
|
-
import DefaultInput from "../../src/components/DefaultInput";
|
|
14
|
-
|
|
15
|
-
describe("Answer component", () => {
|
|
16
|
-
let question,
|
|
17
|
-
onChange,
|
|
18
|
-
answer,
|
|
19
|
-
getOptions,
|
|
20
|
-
loadFormOptions,
|
|
21
|
-
options,
|
|
22
|
-
inputComponent,
|
|
23
|
-
componentsOptions;
|
|
24
|
-
|
|
25
|
-
beforeEach(() => {
|
|
26
|
-
question = {
|
|
27
|
-
"@id": Generator.getRandomUri(),
|
|
28
|
-
};
|
|
29
|
-
question[Constants.LAYOUT_CLASS] = [];
|
|
30
|
-
question[Constants.RDFS_LABEL] = {
|
|
31
|
-
"@language": "en",
|
|
32
|
-
"@value": "1 - Aerodrome General",
|
|
33
|
-
};
|
|
34
|
-
question[Constants.RDFS_COMMENT] = {
|
|
35
|
-
"@language": "en",
|
|
36
|
-
"@value":
|
|
37
|
-
"The identification of the aerodrome/helicopter landing area by name, location and status.",
|
|
38
|
-
};
|
|
39
|
-
onChange = jest.fn();
|
|
40
|
-
options = {
|
|
41
|
-
intl: {
|
|
42
|
-
locale: "en",
|
|
43
|
-
},
|
|
44
|
-
};
|
|
45
|
-
componentsOptions = {
|
|
46
|
-
readOnly: false,
|
|
47
|
-
dateTimeAnswer: {
|
|
48
|
-
dateFormat: "yyyy-MM-dd",
|
|
49
|
-
timeFormat: "HH:mm:ss",
|
|
50
|
-
dateTimeFormat: "yyyy-MM-dd HH:mm:ss",
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
inputComponent = DefaultInput;
|
|
54
|
-
getOptions = jest.fn(() => []);
|
|
55
|
-
loadFormOptions = jest.fn();
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it("renders a Typeahead when layout class is typeahead", () => {
|
|
59
|
-
question[Constants.LAYOUT_CLASS].push(Constants.LAYOUT.QUESTION_TYPEAHEAD);
|
|
60
|
-
const component = mount(
|
|
61
|
-
<ConfigurationContext.Provider
|
|
62
|
-
value={{
|
|
63
|
-
componentsOptions,
|
|
64
|
-
inputComponent,
|
|
65
|
-
options,
|
|
66
|
-
}}
|
|
67
|
-
>
|
|
68
|
-
<FormGenContext.Provider value={{ getOptions, loadFormOptions }}>
|
|
69
|
-
<Answer answer={{}} question={question} onChange={onChange} />
|
|
70
|
-
</FormGenContext.Provider>
|
|
71
|
-
</ConfigurationContext.Provider>
|
|
72
|
-
);
|
|
73
|
-
|
|
74
|
-
const typeahead = component.find(Select);
|
|
75
|
-
expect(typeahead).not.toBeNull();
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it("maps answer object value to string label for the typeahead component", () => {
|
|
79
|
-
const value = Generator.getRandomUri();
|
|
80
|
-
const valueLabel = "masterchief";
|
|
81
|
-
const typeAheadOptions = Generator.generateTypeaheadOptions(
|
|
82
|
-
value,
|
|
83
|
-
valueLabel
|
|
84
|
-
);
|
|
85
|
-
answer = answerWithCodeValue(value);
|
|
86
|
-
getOptions = jest.fn(() => typeAheadOptions);
|
|
87
|
-
question[Constants.HAS_ANSWER] = [answer];
|
|
88
|
-
question[Constants.LAYOUT_CLASS].push(Constants.LAYOUT.QUESTION_TYPEAHEAD);
|
|
89
|
-
question[Constants.HAS_OPTIONS_QUERY] = "SELECT * WHERE {?x ?y ?z. }";
|
|
90
|
-
|
|
91
|
-
const component = mount(
|
|
92
|
-
<ConfigurationContext.Provider
|
|
93
|
-
value={{
|
|
94
|
-
componentsOptions,
|
|
95
|
-
inputComponent,
|
|
96
|
-
options,
|
|
97
|
-
}}
|
|
98
|
-
>
|
|
99
|
-
<FormGenContext.Provider
|
|
100
|
-
value={{ getOptions, loadFormOptions: () => typeAheadOptions }}
|
|
101
|
-
>
|
|
102
|
-
<Answer answer={answer} question={question} onChange={onChange} />
|
|
103
|
-
</FormGenContext.Provider>
|
|
104
|
-
</ConfigurationContext.Provider>
|
|
105
|
-
);
|
|
106
|
-
|
|
107
|
-
waitForComponentToPaint(component);
|
|
108
|
-
const typeahead = component.find(Answer).find(TypeaheadAnswer).find(Select);
|
|
109
|
-
|
|
110
|
-
expect(typeahead).not.toBeNull();
|
|
111
|
-
|
|
112
|
-
expect(typeahead.state("value")[0].name).toEqual(valueLabel);
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
it("loads typeahead options when layout class is typeahead and no possible values are specified", () => {
|
|
116
|
-
question[Constants.LAYOUT_CLASS].push(Constants.LAYOUT.QUESTION_TYPEAHEAD);
|
|
117
|
-
const query = "SELECT * WHERE { ?x ?y ?z .}";
|
|
118
|
-
question[Constants.HAS_OPTIONS_QUERY] = query;
|
|
119
|
-
|
|
120
|
-
const component = mount(
|
|
121
|
-
<ConfigurationContext.Provider
|
|
122
|
-
value={{
|
|
123
|
-
componentsOptions,
|
|
124
|
-
inputComponent,
|
|
125
|
-
options,
|
|
126
|
-
}}
|
|
127
|
-
>
|
|
128
|
-
<FormGenContext.Provider value={{ getOptions, loadFormOptions }}>
|
|
129
|
-
<Answer answer={{}} question={question} onChange={onChange} />
|
|
130
|
-
</FormGenContext.Provider>
|
|
131
|
-
</ConfigurationContext.Provider>
|
|
132
|
-
);
|
|
133
|
-
|
|
134
|
-
waitForComponentToPaint(component);
|
|
135
|
-
|
|
136
|
-
expect(loadFormOptions).toHaveBeenCalled();
|
|
137
|
-
expect(loadFormOptions.mock.calls[0][1]).toEqual(query);
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
function answerWithCodeValue(value) {
|
|
141
|
-
const res = {
|
|
142
|
-
"@id": Generator.getRandomUri(),
|
|
143
|
-
};
|
|
144
|
-
res[Constants.HAS_OBJECT_VALUE] = {
|
|
145
|
-
"@id": value,
|
|
146
|
-
};
|
|
147
|
-
return res;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
it("shows input with text value of the answer when no layout class is specified", () => {
|
|
151
|
-
const value = "masterchief";
|
|
152
|
-
answer = answerWithTextValue(value);
|
|
153
|
-
question[Constants.HAS_ANSWER] = [answer];
|
|
154
|
-
|
|
155
|
-
const component = mount(
|
|
156
|
-
<ConfigurationContext.Provider
|
|
157
|
-
value={{
|
|
158
|
-
componentsOptions,
|
|
159
|
-
inputComponent,
|
|
160
|
-
options,
|
|
161
|
-
}}
|
|
162
|
-
>
|
|
163
|
-
<Answer answer={answer} question={question} onChange={onChange} />s
|
|
164
|
-
</ConfigurationContext.Provider>
|
|
165
|
-
);
|
|
166
|
-
const input = component.find("input");
|
|
167
|
-
|
|
168
|
-
expect(input).not.toBeNull();
|
|
169
|
-
expect(input.props().type).toEqual("text");
|
|
170
|
-
expect(input.props().value).toEqual(value);
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
function answerWithTextValue(value) {
|
|
174
|
-
const res = {
|
|
175
|
-
"@id": Generator.getRandomUri(),
|
|
176
|
-
};
|
|
177
|
-
res[Constants.HAS_DATA_VALUE] = {
|
|
178
|
-
"@language": "en",
|
|
179
|
-
"@value": value,
|
|
180
|
-
};
|
|
181
|
-
return res;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
it("renders date picker with answer value when date layout class is specified", () => {
|
|
185
|
-
const date = new Date("2000-01-01");
|
|
186
|
-
const value = format(date, "yyyy-MM-dd HH:mm:ss");
|
|
187
|
-
|
|
188
|
-
answer = answerWithTextValue(value);
|
|
189
|
-
question[Constants.HAS_ANSWER] = [answer];
|
|
190
|
-
question[Constants.LAYOUT_CLASS].push(Constants.LAYOUT.DATE);
|
|
191
|
-
|
|
192
|
-
const component = mount(
|
|
193
|
-
<ConfigurationContext.Provider
|
|
194
|
-
value={{
|
|
195
|
-
componentsOptions,
|
|
196
|
-
inputComponent,
|
|
197
|
-
options,
|
|
198
|
-
}}
|
|
199
|
-
>
|
|
200
|
-
<Answer answer={answer} question={question} onChange={onChange} />
|
|
201
|
-
</ConfigurationContext.Provider>
|
|
202
|
-
);
|
|
203
|
-
const picker = component.find(DatePicker);
|
|
204
|
-
|
|
205
|
-
expect(picker).not.toBeNull();
|
|
206
|
-
expect(picker.props().showTimeSelect).toEqual(false);
|
|
207
|
-
expect(picker.props().showTimeSelectOnly).toEqual(false);
|
|
208
|
-
expect(picker.props().selected).toEqual(date);
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
it("renders time picker with answer value when time layout class is specified", () => {
|
|
212
|
-
const date = new Date();
|
|
213
|
-
const value = format(date, "HH:mm:ss");
|
|
214
|
-
|
|
215
|
-
answer = answerWithTextValue(value);
|
|
216
|
-
question[Constants.HAS_ANSWER] = [answer];
|
|
217
|
-
question[Constants.LAYOUT_CLASS].push(Constants.LAYOUT.TIME);
|
|
218
|
-
|
|
219
|
-
const component = mount(
|
|
220
|
-
<ConfigurationContext.Provider
|
|
221
|
-
value={{
|
|
222
|
-
componentsOptions,
|
|
223
|
-
inputComponent,
|
|
224
|
-
options,
|
|
225
|
-
}}
|
|
226
|
-
>
|
|
227
|
-
<Answer answer={answer} question={question} onChange={onChange} />
|
|
228
|
-
</ConfigurationContext.Provider>
|
|
229
|
-
);
|
|
230
|
-
const picker = component.find(DatePicker);
|
|
231
|
-
|
|
232
|
-
expect(picker).not.toBeNull();
|
|
233
|
-
expect(picker.props().showTimeSelect).toEqual(true);
|
|
234
|
-
expect(picker.props().showTimeSelectOnly).toEqual(true);
|
|
235
|
-
expect(picker.props().selected).toEqual(new Date(`0 ${value}`));
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
it("renders datetime picker with answer value when datetime layout class is specified", () => {
|
|
239
|
-
const date = new Date();
|
|
240
|
-
const value = format(date, "yyyy-MM-dd HH:mm:ss");
|
|
241
|
-
answer = answerWithTextValue(value);
|
|
242
|
-
question[Constants.HAS_ANSWER] = [answer];
|
|
243
|
-
question[Constants.LAYOUT_CLASS].push(Constants.LAYOUT.DATETIME);
|
|
244
|
-
|
|
245
|
-
const component = mount(
|
|
246
|
-
<ConfigurationContext.Provider
|
|
247
|
-
value={{
|
|
248
|
-
componentsOptions,
|
|
249
|
-
inputComponent,
|
|
250
|
-
options,
|
|
251
|
-
}}
|
|
252
|
-
>
|
|
253
|
-
<Answer answer={answer} question={question} onChange={onChange} />
|
|
254
|
-
</ConfigurationContext.Provider>
|
|
255
|
-
);
|
|
256
|
-
const picker = component.find(DatePicker);
|
|
257
|
-
|
|
258
|
-
expect(picker).not.toBeNull();
|
|
259
|
-
expect(picker.props().showTimeSelect).toEqual(true);
|
|
260
|
-
expect(picker.props().showTimeSelectOnly).toEqual(false);
|
|
261
|
-
expect(picker.props().selected).toEqual(new Date(value));
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
it("renders datetime picker with answer value when no layout class is specified and numeric answer value is used", () => {
|
|
265
|
-
const value = Number(new Date());
|
|
266
|
-
answer = {
|
|
267
|
-
"@id": Generator.getRandomUri(),
|
|
268
|
-
};
|
|
269
|
-
answer[Constants.HAS_DATA_VALUE] = value;
|
|
270
|
-
question[Constants.HAS_ANSWER] = [answer];
|
|
271
|
-
question[Constants.LAYOUT_CLASS].push(Constants.LAYOUT.DATETIME);
|
|
272
|
-
|
|
273
|
-
const component = mount(
|
|
274
|
-
<ConfigurationContext.Provider
|
|
275
|
-
value={{
|
|
276
|
-
componentsOptions,
|
|
277
|
-
inputComponent: { inputComponent },
|
|
278
|
-
options,
|
|
279
|
-
}}
|
|
280
|
-
>
|
|
281
|
-
<Answer answer={answer} question={question} onChange={onChange} />
|
|
282
|
-
</ConfigurationContext.Provider>
|
|
283
|
-
);
|
|
284
|
-
const picker = component.find(DatePicker);
|
|
285
|
-
|
|
286
|
-
expect(picker).not.toBeNull();
|
|
287
|
-
expect(picker.props().showTimeSelect).toEqual(true);
|
|
288
|
-
expect(picker.props().showTimeSelectOnly).toEqual(false);
|
|
289
|
-
expect(picker.props().selected).toEqual(new Date(value));
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
it("renders checkbox with answer value when checkbox layout class is specified", () => {
|
|
293
|
-
const answer = {
|
|
294
|
-
"@id": Generator.getRandomUri(),
|
|
295
|
-
};
|
|
296
|
-
answer[Constants.HAS_DATA_VALUE] = true;
|
|
297
|
-
question[Constants.HAS_ANSWER] = [answer];
|
|
298
|
-
question[Constants.LAYOUT_CLASS].push(Constants.LAYOUT.CHECKBOX);
|
|
299
|
-
|
|
300
|
-
const component = mount(
|
|
301
|
-
<ConfigurationContext.Provider
|
|
302
|
-
value={{
|
|
303
|
-
componentsOptions,
|
|
304
|
-
inputComponent,
|
|
305
|
-
options,
|
|
306
|
-
}}
|
|
307
|
-
>
|
|
308
|
-
<Answer answer={answer} question={question} onChange={onChange} />
|
|
309
|
-
</ConfigurationContext.Provider>
|
|
310
|
-
);
|
|
311
|
-
const input = component.find("input");
|
|
312
|
-
|
|
313
|
-
expect(input).toBeDefined();
|
|
314
|
-
expect(input.props().type).toEqual("checkbox");
|
|
315
|
-
expect(input.props().checked).toBeTruthy();
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
it("renders numeric input with answer value when number layout class is specified", () => {
|
|
319
|
-
const value = 117;
|
|
320
|
-
const answer = {
|
|
321
|
-
"@id": Generator.getRandomUri(),
|
|
322
|
-
};
|
|
323
|
-
answer[Constants.HAS_DATA_VALUE] = value;
|
|
324
|
-
question[Constants.HAS_ANSWER] = [answer];
|
|
325
|
-
question[Constants.HAS_DATATYPE] = Constants.XSD.INT;
|
|
326
|
-
|
|
327
|
-
const component = mount(
|
|
328
|
-
<ConfigurationContext.Provider
|
|
329
|
-
value={{
|
|
330
|
-
componentsOptions,
|
|
331
|
-
inputComponent,
|
|
332
|
-
options,
|
|
333
|
-
}}
|
|
334
|
-
>
|
|
335
|
-
<Answer answer={answer} question={question} onChange={onChange} />
|
|
336
|
-
</ConfigurationContext.Provider>
|
|
337
|
-
);
|
|
338
|
-
const input = component.find("input");
|
|
339
|
-
|
|
340
|
-
expect(input).toBeDefined();
|
|
341
|
-
expect(input.props().type).toEqual("number");
|
|
342
|
-
expect(input.props().value).toEqual(value);
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
it("renders textarea for answer with long value", () => {
|
|
346
|
-
let value = "";
|
|
347
|
-
for (let i = 0; i < Constants.INPUT_LENGTH_THRESHOLD + 1; i++) {
|
|
348
|
-
value += "a";
|
|
349
|
-
}
|
|
350
|
-
answer = answerWithTextValue(value);
|
|
351
|
-
answer[Constants.HAS_DATA_VALUE] = value;
|
|
352
|
-
question[Constants.HAS_ANSWER] = [answer];
|
|
353
|
-
|
|
354
|
-
const component = mount(
|
|
355
|
-
<ConfigurationContext.Provider
|
|
356
|
-
value={{
|
|
357
|
-
componentsOptions,
|
|
358
|
-
inputComponent,
|
|
359
|
-
options,
|
|
360
|
-
}}
|
|
361
|
-
>
|
|
362
|
-
<Answer answer={answer} question={question} onChange={onChange} />
|
|
363
|
-
</ConfigurationContext.Provider>
|
|
364
|
-
);
|
|
365
|
-
const input = component.find("textarea");
|
|
366
|
-
|
|
367
|
-
expect(input).toBeDefined();
|
|
368
|
-
expect(input.props().value).toEqual(value);
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
it("renders masked input for question with masked-input layout class", () => {
|
|
372
|
-
const value = "08/2016";
|
|
373
|
-
const mask = "11/1111";
|
|
374
|
-
const answer = {
|
|
375
|
-
"@id": Generator.getRandomUri(),
|
|
376
|
-
};
|
|
377
|
-
answer[Constants.HAS_DATA_VALUE] = value;
|
|
378
|
-
question[Constants.HAS_ANSWER] = [answer];
|
|
379
|
-
question[Constants.LAYOUT_CLASS].push(Constants.LAYOUT.MASKED_INPUT);
|
|
380
|
-
question[Constants.INPUT_MASK] = mask;
|
|
381
|
-
|
|
382
|
-
const component = mount(
|
|
383
|
-
<ConfigurationContext.Provider
|
|
384
|
-
value={{
|
|
385
|
-
componentsOptions,
|
|
386
|
-
inputComponent,
|
|
387
|
-
options,
|
|
388
|
-
}}
|
|
389
|
-
>
|
|
390
|
-
<Answer answer={answer} question={question} onChange={onChange} />
|
|
391
|
-
</ConfigurationContext.Provider>
|
|
392
|
-
);
|
|
393
|
-
const input = component.find(MaskedInput);
|
|
394
|
-
|
|
395
|
-
expect(input).toBeDefined();
|
|
396
|
-
expect(input.props().value).toEqual(value);
|
|
397
|
-
expect(input.props().mask).toEqual(mask);
|
|
398
|
-
});
|
|
399
|
-
});
|