Skip to content

Commit f4b508a

Browse files
authored
Merge pull request #75 from headwirecom/59-one-of-enums
add OneOfEnum control
2 parents 3ad7590 + 0d84fc5 commit f4b508a

File tree

4 files changed

+289
-0
lines changed

4 files changed

+289
-0
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
The MIT License
3+
4+
Copyright (c) 2020 headwire.com, Inc
5+
https://github.com/headwirecom/jsonforms-react-spectrum-renderers
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in
15+
all copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
THE SOFTWARE.
24+
*/
25+
26+
import {
27+
ControlProps,
28+
isOneOfEnumControl,
29+
RankedTester,
30+
rankWith,
31+
} from '@jsonforms/core';
32+
import { withJsonFormsOneOfEnumProps } from '@jsonforms/react';
33+
import React from 'react';
34+
import { SpectrumInputControl } from './SpectrumInputControl';
35+
import { InputEnum } from '../spectrum-control/InputEnum';
36+
37+
export const SpectrumOneOfEnumControl = (props: ControlProps) => (
38+
<SpectrumInputControl {...props} input={InputEnum} />
39+
);
40+
41+
export const spectrumOneOfEnumControlTester: RankedTester = rankWith(
42+
5,
43+
isOneOfEnumControl
44+
);
45+
46+
export default withJsonFormsOneOfEnumProps(SpectrumOneOfEnumControl);

packages/spectrum/src/controls/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ import SpectrumNumberControl, {
4242
import SpectrumNumberFormattedControl, {
4343
spectrumNumberFormattedControlTester,
4444
} from './SpectrumNumberFormattedControl';
45+
import SpectrumOneOfEnumControl, {
46+
spectrumOneOfEnumControlTester,
47+
} from './SpectrumOneOfEnumControl';
4548
import SpectrumSliderControl, {
4649
spectrumSliderControlTester,
4750
} from './SpectrumSliderControl';
@@ -78,6 +81,8 @@ export {
7881
spectrumNumberControlTester,
7982
SpectrumNumberFormattedControl,
8083
spectrumNumberFormattedControlTester,
84+
SpectrumOneOfEnumControl,
85+
spectrumOneOfEnumControlTester,
8186
SpectrumSliderControl,
8287
spectrumSliderControlTester,
8388
SpectrumTextAreaControl,

packages/spectrum/src/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ import {
6666
spectrumNumberControlTester,
6767
SpectrumNumberFormattedControl,
6868
spectrumNumberFormattedControlTester,
69+
SpectrumOneOfEnumControl,
70+
spectrumOneOfEnumControlTester,
6971
SpectrumSliderControl,
7072
spectrumSliderControlTester,
7173
SpectrumTextAreaControl,
@@ -129,6 +131,10 @@ export const spectrumRenderers: { tester: RankedTester; renderer: any }[] = [
129131
{ tester: spectrumDateControlTester, renderer: SpectrumDateControl },
130132
{ tester: spectrumDateTimeControlTester, renderer: SpectrumDateTimeControl },
131133
{ tester: spectrumEnumControlTester, renderer: SpectrumEnumControl },
134+
{
135+
tester: spectrumOneOfEnumControlTester,
136+
renderer: SpectrumOneOfEnumControl,
137+
},
132138
{ tester: spectrumIntegerControlTester, renderer: SpectrumIntegerControl },
133139
{ tester: spectrumNumberControlTester, renderer: SpectrumNumberControl },
134140
{
Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
/*
2+
The MIT License
3+
4+
Copyright (c) 2017-2019 EclipseSource Munich
5+
https://github.com/eclipsesource/jsonforms
6+
7+
Copyright (c) 2020 headwire.com, Inc
8+
https://github.com/headwirecom/jsonforms-react-spectrum-renderers
9+
10+
Permission is hereby granted, free of charge, to any person obtaining a copy
11+
of this software and associated documentation files (the "Software"), to deal
12+
in the Software without restriction, including without limitation the rights
13+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14+
copies of the Software, and to permit persons to whom the Software is
15+
furnished to do so, subject to the following conditions:
16+
17+
The above copyright notice and this permission notice shall be included in
18+
all copies or substantial portions of the Software.
19+
20+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26+
THE SOFTWARE.
27+
*/
28+
import React from 'react';
29+
import Adapter from 'enzyme-adapter-react-16';
30+
import Enzyme, { mount, ReactWrapper } from 'enzyme';
31+
import { ControlElement, JsonFormsState, update } from '@jsonforms/core';
32+
import { JsonFormsDispatch, JsonFormsReduxContext } from '@jsonforms/react';
33+
import { Provider } from 'react-redux';
34+
import { Store, AnyAction } from 'redux';
35+
import {
36+
defaultTheme,
37+
Provider as SpectrumThemeProvider,
38+
} from '@adobe/react-spectrum';
39+
40+
import SpectrumOneOfEnumControl, {
41+
spectrumOneOfEnumControlTester,
42+
} from '../../src/controls/SpectrumOneOfEnumControl';
43+
import { mountForm } from '../util';
44+
import { initJsonFormsSpectrumStore } from '../spectrumStore';
45+
46+
Enzyme.configure({ adapter: new Adapter() });
47+
48+
const control: ControlElement = {
49+
type: 'Control',
50+
scope: '#/properties/foo',
51+
options: {
52+
disabled: true,
53+
},
54+
};
55+
56+
const fixture = {
57+
data: { foo: 'foo' },
58+
schema: {
59+
type: 'string',
60+
oneOf: [
61+
{
62+
const: 'a',
63+
title: 'Foo',
64+
},
65+
{
66+
const: 'b',
67+
title: 'Bar',
68+
},
69+
],
70+
},
71+
uischema: control,
72+
};
73+
74+
test('tester', () => {
75+
expect(spectrumOneOfEnumControlTester(undefined, undefined)).toBe(-1);
76+
expect(spectrumOneOfEnumControlTester(null, undefined)).toBe(-1);
77+
expect(spectrumOneOfEnumControlTester({ type: 'Foo' }, undefined)).toBe(-1);
78+
expect(spectrumOneOfEnumControlTester({ type: 'Control' }, undefined)).toBe(
79+
-1
80+
);
81+
});
82+
83+
test('tester with wrong prop type', () => {
84+
expect(
85+
spectrumOneOfEnumControlTester(fixture.uischema, {
86+
type: 'object',
87+
properties: { foo: { type: 'string' } },
88+
})
89+
).toBe(-1);
90+
});
91+
92+
test('tester with wrong prop type, but sibling has correct one', () => {
93+
expect(
94+
spectrumOneOfEnumControlTester(fixture.uischema, {
95+
type: 'object',
96+
properties: {
97+
foo: {
98+
type: 'string',
99+
},
100+
bar: fixture.schema,
101+
},
102+
})
103+
).toBe(-1);
104+
});
105+
106+
test('tester with matching string type', () => {
107+
expect(spectrumOneOfEnumControlTester(fixture.uischema, fixture.schema)).toBe(
108+
5
109+
);
110+
});
111+
112+
test('tester with matching numeric type', () => {
113+
expect(
114+
spectrumOneOfEnumControlTester(fixture.uischema, {
115+
type: 'object',
116+
properties: {
117+
foo: {
118+
type: 'number',
119+
oneOf: [
120+
{
121+
const: 1,
122+
title: 'foo',
123+
},
124+
],
125+
},
126+
},
127+
})
128+
).toBe(5);
129+
});
130+
131+
describe('OneOfEnumControl', () => {
132+
let wrapper: ReactWrapper, store: Store<JsonFormsState, AnyAction>;
133+
134+
beforeEach(() => {
135+
store = initJsonFormsSpectrumStore({
136+
data: fixture.data,
137+
schema: fixture.schema,
138+
uischema: fixture.uischema,
139+
});
140+
wrapper = mount(
141+
<Provider store={store}>
142+
<SpectrumThemeProvider theme={defaultTheme}>
143+
<JsonFormsReduxContext>
144+
<JsonFormsDispatch
145+
schema={fixture.schema}
146+
uischema={fixture.uischema}
147+
path='foo'
148+
renderers={[
149+
{
150+
tester: spectrumOneOfEnumControlTester,
151+
renderer: SpectrumOneOfEnumControl,
152+
},
153+
]}
154+
/>
155+
</JsonFormsReduxContext>
156+
</SpectrumThemeProvider>
157+
</Provider>
158+
);
159+
});
160+
161+
afterEach(() => wrapper.unmount());
162+
163+
test('render', () => {
164+
wrapper = mountForm(fixture.uischema, fixture.schema, fixture.data);
165+
166+
const select = wrapper.find('select');
167+
expect(select.props().disabled).toBe(false);
168+
const selectElement = select.getDOMNode() as HTMLSelectElement;
169+
expect(selectElement.tagName).toBe('SELECT');
170+
expect(selectElement.value).toBe('a');
171+
expect(selectElement.options).toHaveLength(2);
172+
expect(selectElement.options.item(0).value).toBe('a');
173+
expect(selectElement.options.item(1).value).toBe('b');
174+
});
175+
176+
test('update via input event', () => {
177+
let state = '';
178+
wrapper = mountForm(
179+
fixture.uischema,
180+
fixture.schema,
181+
fixture.data,
182+
[],
183+
(d) => (state = d.data.foo)
184+
);
185+
const select = wrapper.find('select');
186+
select.simulate('change', { target: { value: 'b' } });
187+
expect(state).toBe('b');
188+
});
189+
190+
test('update via action', () => {
191+
const select = wrapper.find('select').getDOMNode() as HTMLSelectElement;
192+
expect(select.value).toBe('a');
193+
store.dispatch(update('foo', () => 'b'));
194+
setTimeout(() => {
195+
expect(select.value).toBe('b');
196+
expect(select.selectedIndex).toBe(1);
197+
}, 0);
198+
});
199+
200+
test('update with undefined value', () => {
201+
const select = wrapper.find('select').getDOMNode() as HTMLSelectElement;
202+
store.dispatch(update('foo', () => undefined));
203+
setTimeout(() => {
204+
expect(select.selectedIndex).toBe(0);
205+
expect(select.value).toBe('a');
206+
}, 0);
207+
});
208+
209+
test('update with null value', () => {
210+
const select = wrapper.find('select').getDOMNode() as HTMLSelectElement;
211+
store.dispatch(update('foo', () => null));
212+
setTimeout(() => {
213+
expect(select.selectedIndex).toBe(0);
214+
expect(select.value).toBe('a');
215+
}, 0);
216+
});
217+
218+
test('update with wrong ref', () => {
219+
const store = initJsonFormsSpectrumStore({
220+
data: fixture.data,
221+
schema: fixture.schema,
222+
uischema: fixture.uischema,
223+
});
224+
225+
const select = wrapper.find('select').getDOMNode() as HTMLSelectElement;
226+
store.dispatch(update('bar', () => 'ABC'));
227+
setTimeout(() => {
228+
expect(select.selectedIndex).toBe(0);
229+
expect(select.value).toBe('a');
230+
}, 0);
231+
});
232+
});

0 commit comments

Comments
 (0)