Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
beat
beat.editor
Commits
ac831105
Commit
ac831105
authored
Jul 18, 2018
by
Jaden DIEFENBAUGH
Browse files
[js][df] refactor dataformat editor & tests
parent
26eb6b0d
Changes
2
Hide whitespace changes
Inline
Side-by-side
conda/js/src/components/dataformat/DataformatEditor.jsx
View file @
ac831105
...
...
@@ -31,6 +31,7 @@ import CacheInput from '../CacheInput.jsx';
import
DeleteInputBtn
from
'
../DeleteInputBtn.jsx
'
;
import
TypedField
from
'
../TypedField.jsx
'
;
import
*
as
Actions
from
'
@store/actions.js
'
;
import
{
BUILTIN_TYPES
,
getValidDataformatObj
as
getValidObj
}
from
'
@helpers/beat
'
;
import
type
{
BeatObject
,
...
...
@@ -42,10 +43,7 @@ type Props = {
data
:
BeatObject
,
dataformats
:
BeatObject
[],
saveFunc
:
(
BeatObject
)
=>
any
,
};
type
State
=
{
cache
:
any
,
updateFunc
:
(
BeatObject
)
=>
any
,
};
const
isObj
=
(
obj
):
boolean
=>
!
Array
.
isArray
(
obj
)
&&
typeof
obj
===
'
object
'
&&
obj
!==
null
;
...
...
@@ -223,36 +221,24 @@ const RecursiveObj = ({ obj, dfs, updateFunc }: {obj: any, dfs: string[], update
</
div
>
);
export
class
DataformatEditor
extends
React
.
Component
<
Props
,
State
>
{
export
class
DataformatEditor
extends
React
.
Component
<
Props
>
{
constructor
(
props
:
Props
)
{
super
(
props
);
}
state
=
{
cache
:
getValidObj
(
this
.
props
.
data
),
}
componentWillReceiveProps
(
nextProps
:
Props
)
{
this
.
setState
({
cache
:
getValidObj
(
nextProps
.
data
),
});
}
setContents
=
(
newContents
:
any
)
=>
{
this
.
setState
({
cache
:
{
...
this
.
state
.
cache
,
contents
:
{
'
#description
'
:
this
.
state
.
cache
.
contents
[
'
#description
'
],
...
newContents
,
}
this
.
props
.
updateFunc
({
...
this
.
props
.
data
,
contents
:
{
'
#description
'
:
this
.
props
.
data
.
contents
[
'
#description
'
],
...
newContents
,
}
});
}
allDfs
=
()
=>
this
.
props
.
dataformats
.
map
(
d
=>
d
.
name
).
concat
(
BUILTIN_TYPES
);
filteredContents
=
(
obj
:
any
=
this
.
state
.
cache
.
contents
)
=>
Object
.
entries
(
obj
).
filter
(([
n
,
v
])
=>
n
!==
'
#description
'
).
reduce
((
o
,
[
n
,
v
])
=>
({...
o
,
[
n
]:
v
}),
{});
filteredContents
=
(
obj
:
any
=
this
.
props
.
data
.
contents
)
=>
Object
.
entries
(
obj
).
filter
(([
n
,
v
])
=>
n
!==
'
#description
'
).
reduce
((
o
,
[
n
,
v
])
=>
({...
o
,
[
n
]:
v
}),
{});
render
=
()
=>
(
<
div
>
...
...
@@ -261,9 +247,9 @@ export class DataformatEditor extends React.Component<Props, State> {
className
=
'mx-auto'
outline
color
=
'secondary'
onClick
=
{
()
=>
this
.
props
.
saveFunc
(
this
.
state
.
cache
)
}
onClick
=
{
()
=>
this
.
props
.
saveFunc
(
this
.
props
.
data
)
}
>
Save Changes (Changes are
<
ValidSchemaBadge
entity
=
'dataformat'
obj
=
{
this
.
state
.
cache
}
/>
)
Save Changes (Changes are
<
ValidSchemaBadge
entity
=
'dataformat'
obj
=
{
this
.
props
.
data
}
/>
)
</
Button
>
</
div
>
<
Form
onSubmit
=
{
(
e
)
=>
e
.
preventDefault
()
}
>
...
...
@@ -274,8 +260,8 @@ export class DataformatEditor extends React.Component<Props, State> {
type
=
'text'
name
=
'description'
placeholder
=
'Dataformat description...'
value
=
{
this
.
state
.
cache
.
contents
[
'
#description
'
]
}
onChange
=
{
e
=>
this
.
setContents
({
...
this
.
state
.
cache
.
contents
,
'
#description
'
:
e
.
target
.
value
})
}
value
=
{
this
.
props
.
data
.
contents
[
'
#description
'
]
}
onChange
=
{
e
=>
this
.
setContents
({
...
this
.
props
.
data
.
contents
,
'
#description
'
:
e
.
target
.
value
})
}
/>
</
FormGroup
>
</
FormGroup
>
...
...
@@ -287,10 +273,20 @@ export class DataformatEditor extends React.Component<Props, State> {
}
const
mapStateToProps
=
(
state
,
ownProps
)
=>
{
const
dfs
=
Selectors
.
dataformatGet
(
state
);
const
obj
=
{
dataformats
:
Selectors
.
dataformatGet
(
state
),
dataformats
:
dfs
,
data
:
dfs
[
ownProps
.
index
]
||
getValidObj
()
};
return
obj
;
};
export
default
connect
(
mapStateToProps
)(
DataformatEditor
);
const
mapDispatchToProps
=
(
dispatch
,
ownProps
)
=>
({
// replace the obj in the Redux store with the new object
updateFunc
:
(
obj
)
=>
{
console
.
log
(
`dispatching for
${
obj
.
name
}
`
);
dispatch
(
Actions
[
`dataformatUpdate`
](
obj
.
name
,
obj
));
},
});
export
default
connect
(
mapStateToProps
,
mapDispatchToProps
)(
DataformatEditor
);
conda/js/src/components/dataformat/DataformatEditor.spec.jsx
View file @
ac831105
...
...
@@ -5,6 +5,7 @@ import { mount } from 'enzyme';
import
sinon
from
'
sinon
'
;
import
{
spies
}
from
'
@test
'
;
import
{
getValidDataformatObj
as
getValidObj
}
from
'
@helpers/beat
'
;
import
{
DataformatEditor
as
C
}
from
'
.
'
;
import
testDfs
from
'
@test/test_dfs.json
'
;
...
...
@@ -22,26 +23,29 @@ describe('<DataformatEditor />', () => {
{
name
:
'
test/df/1
'
,
contents
:
{
'
#description
'
:
''
,
'
field_1
'
:
'
string
'
,
}
}
].
concat
(
testDfs
);
].
concat
(
testDfs
.
map
(
df
=>
getValidObj
(
df
))
);
dfs
.
forEach
(
function
(
df
){
const
saveFunc
=
()
=>
{};
const
updateFunc
=
()
=>
{};
it
(
`
${
df
.
name
}
`
,
()
=>
{
wrapper
=
mount
(
<
C
data
=
{
df
}
dataformats
=
{
dfs
}
saveFunc
=
{
saveFunc
}
updateFunc
=
{
updateFunc
}
/>
);
expect
(
wrapper
).
to
.
have
.
props
(
[
'
data
'
,
'
dataformats
'
,
'
saveFunc
'
]
[
'
data
'
,
'
dataformats
'
,
'
saveFunc
'
,
'
updateFunc
'
]
).
deep
.
equal
(
[
df
,
dfs
,
saveFunc
]
[
df
,
dfs
,
saveFunc
,
updateFunc
]
);
});
});
...
...
@@ -51,30 +55,39 @@ describe('<DataformatEditor />', () => {
it
(
'
system/integer/1
'
,
()
=>
{
const
dfName
=
'
system/integer/1
'
;
const
saveFunc
=
sinon
.
spy
();
const
_updateFunc
=
(
obj
)
=>
{
wrapper
.
setProps
&&
wrapper
.
setProps
({
data
:
obj
});
};
const
updateFunc
=
sinon
.
spy
(
_updateFunc
);
wrapper
=
mount
(
<
C
data
=
{
{
name
:
dfName
,
contents
:
{}}
}
data
=
{
getValidObj
(
{
name
:
dfName
,
contents
:
{}}
)
}
dataformats
=
{
testDfs
.
filter
(
d
=>
d
.
name
!==
dfName
)
}
saveFunc
=
{
saveFunc
}
updateFunc
=
{
updateFunc
}
/>
);
expect
(
wrapper
).
to
.
have
.
props
(
[
'
data
'
,
'
dataformats
'
,
'
saveFunc
'
]
[
'
data
'
,
'
dataformats
'
,
'
saveFunc
'
,
'
updateFunc
'
]
);
expect
(
wrapper
.
state
(
'
cache
'
)
).
to
.
have
.
property
(
'
name
'
,
dfName
);
expect
(
wrapper
.
props
().
data
).
to
.
have
.
property
(
'
name
'
,
dfName
);
wrapper
.
find
(
'
input[name="description"]
'
).
simulate
(
'
change
'
,
{
target
:
{
value
:
'
Single (32 bits) integer value
'
}});
expect
(
wrapper
.
state
(
'
cache
'
).
contents
).
to
.
have
.
property
(
'
#description
'
,
'
Single (32 bits) integer value
'
);
expect
(
wrapper
.
props
().
data
.
contents
).
to
.
have
.
property
(
'
#description
'
,
'
Single (32 bits) integer value
'
);
expect
(
updateFunc
.
callCount
).
to
.
equal
(
1
);
wrapper
.
find
(
'
button.btn-success
'
).
simulate
(
'
click
'
);
expect
(
updateFunc
.
callCount
).
to
.
equal
(
2
);
wrapper
.
find
(
'
CacheInput[placeholder="Name..."]
'
).
prop
(
'
onChange
'
)(
{
target
:
{
value
:
'
value
'
}});
expect
(
updateFunc
.
callCount
).
to
.
equal
(
3
);
wrapper
.
find
(
'
select
'
).
simulate
(
'
change
'
,
{
target
:
{
value
:
'
int32
'
}});
expect
(
wrapper
.
state
(
'
cache
'
).
contents
).
to
.
have
.
property
(
'
value
'
,
'
int32
'
);
expect
(
updateFunc
.
callCount
).
to
.
equal
(
4
);
expect
(
wrapper
.
props
().
data
.
contents
).
to
.
have
.
property
(
'
value
'
,
'
int32
'
);
expect
(
wrapper
.
state
(
'
cache
'
)
).
to
.
deep
.
equal
({
expect
(
wrapper
.
props
().
data
).
to
.
deep
.
equal
({
'
name
'
:
'
system/integer/1
'
,
'
contents
'
:
{
'
#description
'
:
'
Single (32 bits) integer value
'
,
...
...
@@ -86,11 +99,16 @@ describe('<DataformatEditor />', () => {
it
(
'
system/array_1d_text/1
'
,
()
=>
{
const
dfName
=
'
system/array_1d_text/1
'
;
const
saveFunc
=
sinon
.
spy
();
const
_updateFunc
=
(
obj
)
=>
{
wrapper
.
setProps
&&
wrapper
.
setProps
({
data
:
obj
});
};
const
updateFunc
=
sinon
.
spy
(
_updateFunc
);
wrapper
=
mount
(
<
C
data
=
{
{
name
:
dfName
,
contents
:
{}}
}
data
=
{
getValidObj
(
{
name
:
dfName
,
contents
:
{}}
)
}
dataformats
=
{
testDfs
.
filter
(
d
=>
d
.
name
!==
dfName
)
}
saveFunc
=
{
saveFunc
}
updateFunc
=
{
updateFunc
}
/>
);
...
...
@@ -98,15 +116,15 @@ describe('<DataformatEditor />', () => {
[
'
data
'
,
'
dataformats
'
,
'
saveFunc
'
]
);
expect
(
wrapper
.
state
(
'
cache
'
)
).
to
.
have
.
property
(
'
name
'
,
dfName
);
expect
(
wrapper
.
props
().
data
).
to
.
have
.
property
(
'
name
'
,
dfName
);
wrapper
.
find
(
'
button.btn-success
'
).
simulate
(
'
click
'
);
wrapper
.
find
(
'
CacheInput[placeholder="Name..."]
'
).
prop
(
'
onChange
'
)(
{
target
:
{
value
:
'
text
'
}});
wrapper
.
find
(
'
select
'
).
simulate
(
'
change
'
,
{
target
:
{
value
:
'
array
'
}});
expect
(
wrapper
.
state
(
'
cache
'
)
.
contents
).
to
.
have
.
deep
.
property
(
'
text
'
,
[
0
,
'
string
'
]);
expect
(
wrapper
.
props
().
data
.
contents
).
to
.
have
.
deep
.
property
(
'
text
'
,
[
0
,
'
string
'
]);
expect
(
wrapper
.
state
(
'
cache
'
)
).
to
.
deep
.
equal
({
expect
(
wrapper
.
props
().
data
).
to
.
deep
.
equal
({
'
name
'
:
'
system/array_1d_text/1
'
,
'
contents
'
:
{
'
#description
'
:
''
,
...
...
@@ -121,11 +139,16 @@ describe('<DataformatEditor />', () => {
it
(
'
system/array_2d_floats/1
'
,
()
=>
{
const
dfName
=
'
system/array_2d_floats/1
'
;
const
saveFunc
=
sinon
.
spy
();
const
_updateFunc
=
(
obj
)
=>
{
wrapper
.
setProps
&&
wrapper
.
setProps
({
data
:
obj
});
};
const
updateFunc
=
sinon
.
spy
(
_updateFunc
);
wrapper
=
mount
(
<
C
data
=
{
{
name
:
dfName
,
contents
:
{}}
}
data
=
{
getValidObj
(
{
name
:
dfName
,
contents
:
{}}
)
}
dataformats
=
{
testDfs
.
filter
(
d
=>
d
.
name
!==
dfName
)
}
saveFunc
=
{
saveFunc
}
updateFunc
=
{
updateFunc
}
/>
);
...
...
@@ -133,10 +156,10 @@ describe('<DataformatEditor />', () => {
[
'
data
'
,
'
dataformats
'
,
'
saveFunc
'
]
);
expect
(
wrapper
.
state
(
'
cache
'
)
).
to
.
have
.
property
(
'
name
'
,
dfName
);
expect
(
wrapper
.
props
().
data
).
to
.
have
.
property
(
'
name
'
,
dfName
);
wrapper
.
find
(
'
input[name="description"]
'
).
simulate
(
'
change
'
,
{
target
:
{
value
:
'
Basic format containing a two-dimensional array of float values
'
}});
expect
(
wrapper
.
state
(
'
cache
'
)
.
contents
).
to
.
have
.
property
(
'
#description
'
,
'
Basic format containing a two-dimensional array of float values
'
);
expect
(
wrapper
.
props
().
data
.
contents
).
to
.
have
.
property
(
'
#description
'
,
'
Basic format containing a two-dimensional array of float values
'
);
wrapper
.
find
(
'
button.btn-success
'
).
simulate
(
'
click
'
);
wrapper
.
find
(
'
CacheInput[placeholder="Name..."]
'
).
prop
(
'
onChange
'
)(
{
target
:
{
value
:
'
value
'
}});
...
...
@@ -145,9 +168,9 @@ describe('<DataformatEditor />', () => {
wrapper
.
find
(
'
input[type="number"][min="1"]
'
).
simulate
(
'
change
'
,
{
target
:
{
value
:
'
2
'
}});
wrapper
.
find
(
'
select
'
).
at
(
1
).
simulate
(
'
change
'
,
{
target
:
{
value
:
'
float64
'
}});
expect
(
wrapper
.
state
(
'
cache
'
)
.
contents
).
to
.
have
.
deep
.
property
(
'
value
'
,
[
0
,
0
,
'
float64
'
]);
expect
(
wrapper
.
props
().
data
.
contents
).
to
.
have
.
deep
.
property
(
'
value
'
,
[
0
,
0
,
'
float64
'
]);
expect
(
wrapper
.
state
(
'
cache
'
)
).
to
.
deep
.
equal
({
expect
(
wrapper
.
props
().
data
).
to
.
deep
.
equal
({
'
name
'
:
'
system/array_2d_floats/1
'
,
'
contents
'
:
{
'
#description
'
:
'
Basic format containing a two-dimensional array of float values
'
,
...
...
@@ -163,11 +186,16 @@ describe('<DataformatEditor />', () => {
it
(
'
plot/bar/1
'
,
()
=>
{
const
dfName
=
'
plot/bar/1
'
;
const
saveFunc
=
sinon
.
spy
();
const
_updateFunc
=
(
obj
)
=>
{
wrapper
.
setProps
&&
wrapper
.
setProps
({
data
:
obj
});
};
const
updateFunc
=
sinon
.
spy
(
_updateFunc
);
wrapper
=
mount
(
<
C
data
=
{
{
name
:
dfName
,
contents
:
{}}
}
data
=
{
getValidObj
(
{
name
:
dfName
,
contents
:
{}}
)
}
dataformats
=
{
testDfs
.
filter
(
d
=>
d
.
name
!==
dfName
)
}
saveFunc
=
{
saveFunc
}
updateFunc
=
{
updateFunc
}
/>
);
...
...
@@ -175,40 +203,40 @@ describe('<DataformatEditor />', () => {
[
'
data
'
,
'
dataformats
'
,
'
saveFunc
'
]
);
expect
(
wrapper
.
state
(
'
cache
'
)
).
to
.
have
.
property
(
'
name
'
,
dfName
);
expect
(
wrapper
.
props
().
data
).
to
.
have
.
property
(
'
name
'
,
dfName
);
wrapper
.
find
(
'
input[name="description"]
'
).
simulate
(
'
change
'
,
{
target
:
{
value
:
'
Array of bar plots
'
}});
expect
(
wrapper
.
state
(
'
cache
'
)
.
contents
).
to
.
have
.
property
(
'
#description
'
,
'
Array of bar plots
'
);
expect
(
wrapper
.
props
().
data
.
contents
).
to
.
have
.
property
(
'
#description
'
,
'
Array of bar plots
'
);
// 'data' field
wrapper
.
find
(
'
.dfLevel button.btn-success
'
).
simulate
(
'
click
'
);
wrapper
.
find
(
'
.dfLevel .field0 CacheInput[placeholder="Name..."]
'
).
prop
(
'
onChange
'
)(
{
target
:
{
value
:
'
data
'
}});
wrapper
.
find
(
'
.dfLevel .field0 select
'
).
simulate
(
'
change
'
,
{
target
:
{
value
:
'
array
'
}});
wrapper
.
find
(
'
.dfLevel .field0 select.subtype
'
).
simulate
(
'
change
'
,
{
target
:
{
value
:
'
object
'
}});
expect
(
wrapper
.
state
(
'
cache
'
)
.
contents
).
to
.
have
.
deep
.
property
(
'
data
'
,
[
0
,
{}]);
expect
(
wrapper
.
props
().
data
.
contents
).
to
.
have
.
deep
.
property
(
'
data
'
,
[
0
,
{}]);
// 'label' subfield
wrapper
.
find
(
'
.dfLevel .field0 .dfLevel button.btn-success
'
).
simulate
(
'
click
'
);
wrapper
.
find
(
'
.dfLevel .field0 .dfLevel .field0 CacheInput[placeholder="Name..."]
'
).
prop
(
'
onChange
'
)(
{
target
:
{
value
:
'
label
'
}});
wrapper
.
find
(
'
.dfLevel .field0 .dfLevel .field0 select
'
).
simulate
(
'
change
'
,
{
target
:
{
value
:
'
string
'
}});
expect
(
wrapper
.
state
(
'
cache
'
)
.
contents
.
data
[
1
]).
to
.
have
.
deep
.
property
(
'
label
'
,
'
string
'
);
expect
(
wrapper
.
props
().
data
.
contents
.
data
[
1
]).
to
.
have
.
deep
.
property
(
'
label
'
,
'
string
'
);
// 'x' subfield
wrapper
.
find
(
'
.dfLevel .field0 .dfLevel button.btn-success
'
).
simulate
(
'
click
'
);
wrapper
.
find
(
'
.dfLevel .field0 .dfLevel .field1 CacheInput[placeholder="Name..."]
'
).
prop
(
'
onChange
'
)(
{
target
:
{
value
:
'
x
'
}});
wrapper
.
find
(
'
.dfLevel .field0 .dfLevel .field1 select
'
).
simulate
(
'
change
'
,
{
target
:
{
value
:
'
array
'
}});
wrapper
.
find
(
'
.dfLevel .field0 .dfLevel .field1 select.subtype
'
).
simulate
(
'
change
'
,
{
target
:
{
value
:
'
float64
'
}});
expect
(
wrapper
.
state
(
'
cache
'
)
.
contents
.
data
[
1
]).
to
.
have
.
deep
.
property
(
'
x
'
,
[
0
,
'
float64
'
]);
expect
(
wrapper
.
props
().
data
.
contents
.
data
[
1
]).
to
.
have
.
deep
.
property
(
'
x
'
,
[
0
,
'
float64
'
]);
// 'y' subfield
wrapper
.
find
(
'
.dfLevel .field0 .dfLevel button.btn-success
'
).
simulate
(
'
click
'
);
wrapper
.
find
(
'
.dfLevel .field0 .dfLevel .field2 CacheInput[placeholder="Name..."]
'
).
prop
(
'
onChange
'
)(
{
target
:
{
value
:
'
y
'
}});
wrapper
.
find
(
'
.dfLevel .field0 .dfLevel .field2 select
'
).
simulate
(
'
change
'
,
{
target
:
{
value
:
'
array
'
}});
wrapper
.
find
(
'
.dfLevel .field0 .dfLevel .field2 select.subtype
'
).
simulate
(
'
change
'
,
{
target
:
{
value
:
'
float64
'
}});
expect
(
wrapper
.
state
(
'
cache
'
)
.
contents
.
data
[
1
]).
to
.
have
.
deep
.
property
(
'
y
'
,
[
0
,
'
float64
'
]);
expect
(
wrapper
.
props
().
data
.
contents
.
data
[
1
]).
to
.
have
.
deep
.
property
(
'
y
'
,
[
0
,
'
float64
'
]);
expect
(
wrapper
.
state
(
'
cache
'
)
).
to
.
deep
.
equal
({
expect
(
wrapper
.
props
().
data
).
to
.
deep
.
equal
({
'
name
'
:
'
plot/bar/1
'
,
'
contents
'
:
{
'
#description
'
:
'
Array of bar plots
'
,
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment