Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
simmctic
form-creator
form-creator-api
Commits
976aad3f
Commit
976aad3f
authored
Oct 06, 2020
by
Richard Fernando Heise Ferreira
Browse files
Issue
#80
: Add times an form can be answered
Signed-off-by:
Richard Heise
<
rfhf19@inf.ufpr.br
>
parent
e56910ee
Pipeline
#23871
passed with stages
in 4 minutes and 45 seconds
Changes
13
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
CHANGELOG.md
View file @
976aad3f
...
...
@@ -5,6 +5,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to
[
Semantic Versioning
](
https://semver.org/spec/v2.0.0.html
)
.
## 1.2.7 - 13/10/2020
## Added
-
Property times added to form table #80 (Richard Heise)
## 1.2.6 - 19/06/2020
## Added
-
A extra function on optHandler to better handle form edits #77 (Richard Heise)
...
...
form-creator-database
@
4471b8cf
Compare
6cd530d9
...
4471b8cf
Subproject commit
6cd530d9f009f739a7f285efddae4d29377dad7c
Subproject commit
4471b8cfc730d87b0d87882e4ccc0ffde1da189a
package.json
View file @
976aad3f
{
"name"
:
"form-creator-api"
,
"version"
:
"1.2.
6
"
,
"version"
:
"1.2.
7
"
,
"description"
:
"RESTful API used to manage and answer forms."
,
"main"
:
"index.js"
,
"scripts"
:
{
...
...
src/api/controllers/form.spec.ts
View file @
976aad3f
...
...
@@ -22,17 +22,10 @@
import
{
series
,
waterfall
}
from
"
async
"
;
import
*
as
request
from
"
supertest
"
;
import
{
expect
}
from
"
chai
"
;
import
{
QueryResult
}
from
"
pg
"
;
import
*
as
server
from
"
../../main
"
;
import
{
EnumHandler
,
InputType
,
UpdateType
,
ValidationType
}
from
"
../../utils/enumHandler
"
;
import
{
TestHandler
}
from
"
../../utils/testHandler
"
;
import
{
OptHandler
}
from
"
../../utils/optHandler
"
;
import
{
Form
,
FormOptions
}
from
"
../../core/form
"
;
import
{
FormUpdate
,
FormUpdateOptions
}
from
"
../../core/formUpdate
"
;
import
{
Input
,
InputOptions
,
Validation
}
from
"
../../core/input
"
;
import
{
InputUpdate
,
InputUpdateOptions
}
from
"
../../core/inputUpdate
"
;
import
{
DbHandler
}
from
"
../../utils/dbHandler
"
;
import
{
configs
}
from
"
../../utils/config
"
;
import
{
Fixture
}
from
"
../../../test/fixture
"
;
import
{
formScenario
}
from
"
../../../test/scenario
"
;
...
...
@@ -103,6 +96,7 @@ describe("API data controller - form", () => {
expect
(
res
.
body
).
to
.
be
.
an
(
"
object
"
);
const
form
:
Form
=
new
Form
(
OptHandler
.
form
(
res
.
body
));
expect
(
form
.
answerTimes
).
to
.
be
.
equal
(
false
);
TestHandler
.
testForm
(
form
,
new
Form
(
OptHandler
.
form
(
formScenario
.
validForm
)));
})
...
...
@@ -300,4 +294,5 @@ describe("API data controller - form", () => {
})
.
end
(
done
);
});
});
src/api/controllers/form.ts
View file @
976aad3f
...
...
@@ -70,7 +70,9 @@ export class FormCtrl {
,
title
:
formResult
.
title
,
description
:
formResult
.
description
,
inputs
:
[]
,
answerTimes
:
formResult
.
answerTimes
};
const
formUpdate
:
FormUpdate
=
DiffHandler
.
diff
(
formResult
,
new
Form
(
formOpts
));
callback
(
null
,
formUpdate
);
...
...
src/api/controllers/user.spec.ts
View file @
976aad3f
...
...
@@ -191,6 +191,9 @@ describe("API data controller", () => {
.
expect
(
200
)
.
expect
((
res
:
any
)
=>
{
expect
(
res
.
body
).
to
.
be
.
an
(
"
array
"
);
res
.
body
.
sort
(
function
(
a
:
any
,
b
:
any
)
{
return
a
.
id
-
b
.
id
})
let
j
:
number
=
1
;
for
(
const
i
of
res
.
body
)
{
expect
(
i
.
id
).
to
.
be
.
eql
(
j
++
);
...
...
src/api/controllers/user.ts
View file @
976aad3f
...
...
@@ -248,6 +248,7 @@ export class UserCtrl {
,
title
:
form
.
title
,
description
:
form
.
description
,
answersNumber
:
0
,
answerTimes
:
form
.
answerTimes
,
date
:
""
}));
...
...
src/core/form.ts
View file @
976aad3f
...
...
@@ -35,31 +35,37 @@ export interface FormOptions {
/** Array of input. containing question */
inputs
:
InputOptions
[];
/** Number of times an user can answer this form */
answerTimes
?:
boolean
;
}
/**
* Form Class to manage project's forms
*/
export
class
Form
{
/** Unique identifier of a Form instance */
public
readonly
id
:
number
;
/** Form's title. An human-understandable identifier. Not unique */
public
readonly
title
:
string
;
/** Form Description, as propose */
public
readonly
description
:
string
;
/** Array of input. containing question */
public
readonly
inputs
:
Input
[];
/** Unique identifier of a Form instance */
public
readonly
id
:
number
;
/** Form's title. An human-understandable identifier. Not unique */
public
readonly
title
:
string
;
/** Form Description, as propose */
public
readonly
description
:
string
;
/** Array of input. containing question */
public
readonly
inputs
:
Input
[];
/** Number of times an user can answer this form */
public
readonly
answerTimes
:
boolean
;
/**
* Creates a new instance of Form Class
* @param options - FormOptions instance to create a form.
*/
constructor
(
options
:
FormOptions
)
{
this
.
id
=
options
.
id
?
options
.
id
:
null
;
this
.
title
=
options
.
title
;
this
.
description
=
options
.
description
;
this
.
inputs
=
options
.
inputs
.
map
((
i
:
any
)
=>
{
return
new
Input
(
OptHandler
.
input
(
i
));
});
}
constructor
(
options
:
FormOptions
)
{
this
.
id
=
options
.
id
?
options
.
id
:
null
;
this
.
title
=
options
.
title
;
this
.
description
=
options
.
description
;
this
.
inputs
=
options
.
inputs
.
map
((
i
:
any
)
=>
{
return
new
Input
(
OptHandler
.
input
(
i
));
});
this
.
answerTimes
=
options
.
answerTimes
?
options
.
answerTimes
:
false
;
}
}
}
src/utils/answerQueryBuilder.ts
View file @
976aad3f
...
...
@@ -24,7 +24,7 @@ import { Pool, QueryResult } from "pg";
import
{
Form
}
from
"
../core/form
"
;
import
{
FormAnswer
,
FormAnswerOptions
}
from
"
../core/formAnswer
"
;
import
{
InputAnswer
,
InputAnswerOptions
,
InputAnswerOptionsDict
}
from
"
../core/inputAnswer
"
;
import
{
ErrorHandler
}
from
"
./errorHandler
"
;
import
{
ErrorHandler
}
from
"
./errorHandler
"
;
import
{
FormQueryBuilder
}
from
"
./formQueryBuilder
"
;
import
{
OptHandler
}
from
"
./optHandler
"
;
import
{
QueryBuilder
,
QueryOptions
}
from
"
./queryBuilder
"
;
...
...
@@ -40,7 +40,7 @@ export class AnswerQueryBuilder extends QueryBuilder {
constructor
(
builder
:
FormQueryBuilder
,
pool
:
Pool
)
{
super
(
pool
);
this
.
formQueryBuilder
=
builder
;
}
}
/**
* Asynchronously write a Answer on database.
...
...
@@ -52,7 +52,7 @@ export class AnswerQueryBuilder extends QueryBuilder {
public
write
(
formAnswer
:
FormAnswer
,
cb
:
(
err
:
Error
,
result
?:
FormAnswer
)
=>
void
)
{
waterfall
([
(
callback
:
(
err
:
Error
,
result
?:
QueryResult
)
=>
void
)
=>
{
(
callback
:
(
err
:
Error
,
result
?:
QueryResult
)
=>
void
)
=>
{
this
.
begin
((
error
:
Error
)
=>
{
callback
(
error
);
});
...
...
@@ -192,12 +192,12 @@ export class AnswerQueryBuilder extends QueryBuilder {
};
this
.
executeQuery
(
query
,
(
err
:
Error
,
result
?:
QueryResult
)
=>
{
if
(
err
){
if
(
err
)
{
cb
(
err
);
return
;
}
if
(
result
.
rowCount
!==
1
){
if
(
result
.
rowCount
!==
1
)
{
cb
(
ErrorHandler
.
notInserted
(
"
FormAnswer
"
));
return
;
}
...
...
@@ -264,12 +264,12 @@ export class AnswerQueryBuilder extends QueryBuilder {
};
this
.
executeQuery
(
query
,
(
err
:
Error
,
result
?:
QueryResult
)
=>
{
if
(
err
){
if
(
err
)
{
cb
(
err
);
return
;
}
if
(
result
.
rowCount
!==
1
){
if
(
result
.
rowCount
!==
1
)
{
cb
(
ErrorHandler
.
notInserted
(
"
InputsAnswer
"
));
return
;
}
...
...
@@ -278,16 +278,16 @@ export class AnswerQueryBuilder extends QueryBuilder {
});
}
/**
* Asynchronously read a FormAnswer from database.
* @param formAnswerId - FormAnswer identifier to be founded.
* @param cb - Callback function which contains the data read.
* @param cb.err - Error information when the method fails.
* @param cb.formAnswers - FormAnswer object or null if form not exists.
*/
/**
* Asynchronously read a FormAnswer from database.
* @param formAnswerId - FormAnswer identifier to be founded.
* @param cb - Callback function which contains the data read.
* @param cb.err - Error information when the method fails.
* @param cb.formAnswers - FormAnswer object or null if form not exists.
*/
public
read
(
formAnswerId
:
number
,
cb
:
(
err
:
Error
,
formAnswers
?:
FormAnswer
)
=>
void
)
{
waterfall
([
(
callback
:
(
err
:
Error
,
result
?:
QueryResult
)
=>
void
)
=>
{
(
callback
:
(
err
:
Error
,
result
?:
QueryResult
)
=>
void
)
=>
{
this
.
begin
((
error
:
Error
)
=>
{
callback
(
error
);
});
...
...
@@ -333,7 +333,7 @@ export class AnswerQueryBuilder extends QueryBuilder {
*/
public
readAll
(
formId
:
number
,
cb
:
(
err
:
Error
,
formAnswers
?:
FormAnswer
[])
=>
void
)
{
waterfall
([
(
callback
:
(
err
:
Error
,
result
?:
QueryResult
)
=>
void
)
=>
{
(
callback
:
(
err
:
Error
,
result
?:
QueryResult
)
=>
void
)
=>
{
this
.
begin
((
error
:
Error
)
=>
{
callback
(
error
);
});
...
...
@@ -467,6 +467,7 @@ export class AnswerQueryBuilder extends QueryBuilder {
,
title
:
undefined
,
description
:
undefined
,
inputs
:
[]
,
answerTimes
:
answerResult
.
answerTimes
};
const
formAnswerTmp
:
FormAnswerOptions
=
{
id
:
answerResult
.
id
...
...
@@ -528,7 +529,7 @@ export class AnswerQueryBuilder extends QueryBuilder {
* @param cb.err - Error information when the method fails.
*/
private
readSubFormController
(
inputAnswer
:
InputAnswerOptions
,
inputAnswerArray
:
InputAnswerOptions
[],
cb
:
(
err
:
Error
)
=>
void
)
{
if
(
inputAnswer
.
subForm
===
null
)
{
if
(
inputAnswer
.
subForm
===
null
)
{
inputAnswerArray
.
push
(
inputAnswer
);
cb
(
null
);
return
;
...
...
src/utils/diffHandler.ts
View file @
976aad3f
...
...
@@ -46,7 +46,9 @@ export class DiffHandler {
const
formUpdate
:
FormUpdate
=
{
form
:
newForm
,
updateDate
:
new
Date
()
,
changed
:
((
newForm
.
title
!==
oldForm
.
title
)
||
(
newForm
.
description
!==
oldForm
.
description
))
,
changed
:
((
newForm
.
title
!==
oldForm
.
title
)
||
(
newForm
.
description
!==
oldForm
.
description
)
||
(
newForm
.
answerTimes
!==
oldForm
.
answerTimes
))
,
inputUpdates
:
[]
};
...
...
@@ -55,7 +57,7 @@ export class DiffHandler {
while
((
i
<
sortedOldInputs
.
length
)
&&
(
j
<
sortedNewInputs
.
length
))
{
if
(
sortedNewInputs
[
j
][
"
id
"
]
===
sortedOldInputs
[
i
][
"
id
"
])
{
if
(
sortedNewInputs
[
j
].
placement
!==
sortedOldInputs
[
i
].
placement
)
{
if
(
sortedNewInputs
[
j
].
placement
!==
sortedOldInputs
[
i
].
placement
)
{
formUpdate
.
inputUpdates
.
push
(
DiffHandler
.
swapInput
(
sortedNewInputs
[
j
],
sortedOldInputs
[
i
]));
}
j
++
;
...
...
src/utils/formQueryBuilder.ts
View file @
976aad3f
...
...
@@ -95,7 +95,7 @@ export class FormQueryBuilder extends QueryBuilder {
* @param cb.err - Error information when the method fails.
*/
private
executeListForms
(
userId
:
number
,
cb
:
(
err
:
Error
,
forms
?:
Form
[])
=>
void
)
{
const
queryString
:
string
=
"
SELECT t1.id,t1.title,t1.description FROM form t1
\
const
queryString
:
string
=
"
SELECT t1.id,t1.title,t1.description
,t1.times
FROM form t1
\
INNER JOIN form_owner t2 ON (t1.id=t2.id_form
\
AND t2.id_user=$1);
"
;
const
query
:
QueryOptions
=
{
...
...
@@ -119,10 +119,10 @@ export class FormQueryBuilder extends QueryBuilder {
,
title
:
row
[
"
title
"
]
,
description
:
row
[
"
description
"
]
,
inputs
:
[]
,
answerTimes
:
row
[
"
times
"
]
};
const
formTmp
:
Form
=
new
Form
(
formOpt
);
forms
.
push
(
formTmp
);
}
...
...
@@ -250,6 +250,7 @@ export class FormQueryBuilder extends QueryBuilder {
,
title
:
result
.
rows
[
0
][
"
title
"
]
,
description
:
result
.
rows
[
0
][
"
description
"
]
,
inputs
:
[]
,
answerTimes
:
result
.
rows
[
0
][
"
times
"
]
});
callback
(
null
,
formTmp
);
...
...
@@ -420,6 +421,7 @@ export class FormQueryBuilder extends QueryBuilder {
,
title
:
form
.
title
,
description
:
form
.
description
,
inputs
:
inputsTmp
,
answerTimes
:
form
.
answerTimes
});
anotherCallback
(
null
,
formTmp
);
}
...
...
@@ -467,7 +469,7 @@ export class FormQueryBuilder extends QueryBuilder {
* @param cb.form - Form or null if form not exists.
*/
private
executeReadForm
(
id
:
number
,
cb
:
(
err
:
Error
,
form
?:
QueryResult
)
=>
void
)
{
const
queryString
:
string
=
"
SELECT id, title, description FROM form WHERE id=$1;
"
;
const
queryString
:
string
=
"
SELECT id, title, description
, times
FROM form WHERE id=$1;
"
;
const
query
:
QueryOptions
=
{
query
:
queryString
,
parameters
:
[
id
]
...
...
@@ -775,14 +777,15 @@ export class FormQueryBuilder extends QueryBuilder {
* @param cb.result - Form identifier or null if any error occurs.
*/
private
executeWriteForm
(
form
:
Form
,
cb
:
(
err
:
Error
,
result
?:
number
)
=>
void
)
{
const
queryString
:
string
=
"
INSERT INTO form (title, description)
\
VALUES ($1, $2)
\
const
queryString
:
string
=
"
INSERT INTO form (title, description
, times
)
\
VALUES ($1, $2
, $3
)
\
RETURNING id;
"
;
const
query
:
QueryOptions
=
{
query
:
queryString
,
parameters
:
[
form
.
title
,
form
.
description
,
form
.
answerTimes
]
};
...
...
@@ -1035,6 +1038,9 @@ export class FormQueryBuilder extends QueryBuilder {
},
(
callback
:
(
err
:
Error
)
=>
void
)
=>
{
this
.
executeUpdateForm
(
form
.
description
,
form
.
id
,
"
description
"
,
callback
);
},
(
callback
:
(
err
:
Error
)
=>
void
)
=>
{
this
.
executeUpdateForm
(
form
.
answerTimes
,
form
.
id
,
"
times
"
,
callback
);
}
],
(
error
)
=>
{
cb
(
error
);
...
...
@@ -1194,7 +1200,7 @@ export class FormQueryBuilder extends QueryBuilder {
* @param cb - Callback function.
* @param cb.err - Error information when method fails.
*/
private
executeUpdateForm
(
value
:
string
,
id
:
number
,
field
:
string
,
cb
:
(
err
:
Error
)
=>
void
)
{
private
executeUpdateForm
(
value
:
any
,
id
:
number
,
field
:
string
,
cb
:
(
err
:
Error
)
=>
void
)
{
const
queryString
:
string
=
"
UPDATE form SET
"
+
field
+
"
= $1 WHERE id = $2
"
;
const
query
:
QueryOptions
=
{
query
:
queryString
...
...
src/utils/optHandler.ts
View file @
976aad3f
...
...
@@ -54,7 +54,8 @@ export class OptHandler {
title
:
obj
.
title
,
description
:
obj
.
description
,
id
:
obj
.
id
,
inputs
:
obj
.
inputs
.
map
((
i
:
any
)
=>
OptHandler
.
input
(
i
))
inputs
:
obj
.
inputs
.
map
((
i
:
any
)
=>
OptHandler
.
input
(
i
)),
answerTimes
:
obj
.
answerTimes
};
return
option
;
...
...
@@ -323,7 +324,8 @@ export class OptHandler {
title
:
obj
.
title
,
description
:
obj
.
description
,
id
:
obj
.
id
,
inputs
:
obj
.
inputs
.
map
((
i
:
any
)
=>
OptHandler
.
input
(
i
))
inputs
:
obj
.
inputs
.
map
((
i
:
any
)
=>
OptHandler
.
input
(
i
)),
answerTimes
:
obj
.
answerTimes
};
return
option
;
...
...
test/scenario.ts
View file @
976aad3f
...
...
@@ -549,7 +549,8 @@ const form1: Form = {
,
inputs
:
[
Input1
,
Input2
]
],
answerTimes
:
true
};
/** New form with one more Input */
...
...
@@ -562,7 +563,8 @@ const form2: Form = {
,
Input2
,
Input3
,
Input4
]
],
answerTimes
:
true
};
/** New form with swapped inputs */
const
form3
:
Form
=
{
...
...
@@ -573,7 +575,8 @@ const form3: Form = {
Input1Otherplacement
,
Input2Placement0
,
Input3
]
],
answerTimes
:
true
};
/** New form with inputs that were removed and added */
const
form4
:
Form
=
{
...
...
@@ -584,7 +587,8 @@ const form4: Form = {
Input1UndefinedID
,
Input2UndefinedID
,
Input3UndefinedID
]
],
answerTimes
:
true
};
/** New form resulting from the aplication of all operations */
const
form5
:
Form
=
{
...
...
@@ -596,7 +600,8 @@ const form5: Form = {
,
Input2Placement0id2
,
Input3OtherID
,
Input4
]
],
answerTimes
:
true
};
/** New form resulting from the restoration of an Input */
const
form6
:
Form
=
{
...
...
@@ -607,7 +612,8 @@ const form6: Form = {
Input1
,
Input2Placement2id2
,
Input3Placement1id3
]
],
answerTimes
:
true
};
/** New form */
const
form7
:
Form
=
{
...
...
@@ -618,7 +624,8 @@ const form7: Form = {
Input1Empty
,
Input2Placement0idNULL
,
Input3idNULL
]
],
answerTimes
:
true
};
/** New form created with a wrong title */
const
form8
:
Form
=
{
...
...
@@ -628,7 +635,8 @@ const form8: Form = {
,
inputs
:
[
Input1
,
Input2
]
],
answerTimes
:
true
};
/** New form created */
const
formToRead
:
Form
=
{
...
...
@@ -638,7 +646,8 @@ const formToRead: Form = {
,
inputs
:
[
Input1
,
Input2
]
],
answerTimes
:
true
};
/** Old form that serves as a base for comparison */
const
formBase
:
Form
=
{
...
...
@@ -649,7 +658,8 @@ const formBase: Form = {
Input1
,
Input2
,
Input3
]
],
answerTimes
:
true
};
/** Another old form that serves as a base for comparison */
const
formBase2
:
Form
=
{
...
...
@@ -660,7 +670,8 @@ const formBase2: Form = {
Input1
,
Input2id2
,
Input4Placement2id4
]
],
answerTimes
:
true
};
/** Another old form that serves as a base for comparison */
const
formBase3
:
Form
=
{
...
...
@@ -670,7 +681,8 @@ const formBase3: Form = {
,
inputs
:
[
Input1
,
mixedInput1
]
],
answerTimes
:
true
};
/** Empty form used as a base for comparison */
const
emptyForm
:
Form
=
{
...
...
@@ -678,6 +690,7 @@ const emptyForm: Form = {
,
title
:
"
Form Title 1
"
,
description
:
"
Form Description 1
"
,
inputs
:
[]
,
answerTimes
:
true
};
/** Expected input update to check an form update with a 'remove' type */
const
expInput1
:
InputUpdate
=
{
...
...
@@ -1087,6 +1100,7 @@ const expFormtoUpdateNullId: Form = {
,
title
:
"
Form Title 1
"
,
description
:
"
Form Description 1
"
,
inputs
:
[
Input1
]
,
answerTimes
:
true
};
/** Expected form update having null id */
const
expFormUpdate
:
FormUpdate
=
{
...
...
@@ -1175,7 +1189,8 @@ const formMissingTitle: any = {
OptHandler
.
input
(
optsInput1
)
,
OptHandler
.
input
(
optsInput2
)
,
OptHandler
.
input
(
optsInput3
)
]
],
answerTimes
:
true
};
/** Form that has no description atribute */
const
formMissingDescription
:
any
=
{
...
...
@@ -1185,13 +1200,15 @@ const formMissingDescription: any = {
OptHandler
.
input
(
optsInput1
)
,
OptHandler
.
input
(
optsInput2
)
,
OptHandler
.
input
(
optsInput3
)
]
],
answerTimes
:
true
};
/** Form that has no input atribute */
const
formMissingInputs
:
any
=
{
id
:
1
,
title
:
"
Form Title 1
"
,
description
:
"
Form Description 1
"
,
answerTimes
:
true
};
/** Input that has no placement atribute */
const
inputMissingPlacement
:
any
=
{
...
...
@@ -1330,7 +1347,8 @@ const fullFormOptions: FormOptions = {
OptHandler
.
input
(
optsInput1
)
,
OptHandler
.
input
(
optsInput2
)
,
OptHandler
.
input
(
optsInput3
)
]
],
answerTimes
:
true
};
const
formForAnswer
:
Form
=
{
id
:
1
...
...
@@ -1340,7 +1358,8 @@ const formForAnswer: Form = {
Input1
,
Input2
,
Input3
]
],
answerTimes
:
true
};
/** Valid form created used fullFormOptions */
const
tmpForm
:
Form
=
new
Form
(
OptHandler
.
form
(
fullFormOptions
));
...
...
@@ -1422,7 +1441,8 @@ const validFormUpdateObj: any = {
updateObj1
,
updateObj2
,
updateObj3
]
],
answerTimes
:
true
};
/** FormUpdate with non-array inputUpdates */
const
formUpdateNotArrayInputUpdates
:
any
=
{
...
...
@@ -1439,7 +1459,8 @@ const formUpdateMissingForm: any = {
updateObj1
,
updateObj2
,
updateObj3
]
],
answerTimes
:
true
};
/** FormUpdate missing the inputs to update */
const
formUpdateMissinginputUpdate
:
any
=
{
...
...
@@ -1759,7 +1780,8 @@ const formWithValidSubForm1: FormOptions = {
,
inputs
:
[
new
Input
(
inputOptWithValidSubForm1
)
,
new
Input
(
inputOpt1ForForm8
)
]
],
answerTimes
:
true
};
/** A form with a valid SubForm */
const
formWithValidSubForm2
:
FormOptions
=
{
...
...
@@ -1769,7 +1791,8 @@ const formWithValidSubForm2: FormOptions = {
,
inputs
:
[
new
Input
(
inputOptWithValidSubForm5
)
,
new
Input
(
inputOpt1ForForm11
)
]
],
answerTimes
:
true
};
/** A form with a invalid SubForm */
const
formWithInvalidSubForm1
:
FormOptions
=
{
...
...
@@ -1779,7 +1802,8 @@ const formWithInvalidSubForm1: FormOptions = {
,
inputs
:
[
inputOptWithInvalidSubForm1
,
inputOpt1ForForm9
]
],
answerTimes
:
true
};
/** A form with a invalid SubForm */
...
...
@@ -1790,7 +1814,8 @@ const formWithInvalidSubForm2: FormOptions = {
,
inputs
:
[
inputOptWithInvalidSubForm2
,
inputOpt1ForForm9
]
],
answerTimes
:
true
};
/** A updated version of form 8 */
...
...
@@ -1801,7 +1826,8 @@ const updatedFormWithValidSubForm1: FormOptions = {
,
inputs
:
[
inputOptWithValidSubForm2
,
inputOpt2ForForm8
]
],
answerTimes
:
true
};
/** A updated version of form 8 */
const
updatedFormWithValidSubForm2
:
FormOptions
=
{
...
...
@@ -1811,7 +1837,8 @@ const updatedFormWithValidSubForm2: FormOptions = {
,
inputs
:
[
inputOpt3ForForm8
,
inputOptWithValidSubForm3
]
],
answerTimes
:
true
};
/** A invalid updated version of form 8 */
...
...
@@ -1823,7 +1850,8 @@ const updatedFormWithInvalidSubForm1: FormOptions = {
inputOpt3ForForm8
,
inputOptWithValidSubForm3