Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
clean-and-itasks
iTasks-SDK
Commits
80c2f191
Commit
80c2f191
authored
Jul 19, 2018
by
Bas Lijnse
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added unit tests to reproduce bug in composition of layout rules.
parent
7d5cb944
Pipeline
#12978
failed with stage
in 10 minutes and 4 seconds
Changes
3
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
335 additions
and
1 deletion
+335
-1
Tests/Unit/iTasks.UI.Editor.Generic.UnitTests.prj.default
Tests/Unit/iTasks.UI.Editor.Generic.UnitTests.prj.default
+68
-0
Tests/Unit/iTasks/UI/Editor/Generic/UnitTests.icl
Tests/Unit/iTasks/UI/Editor/Generic/UnitTests.icl
+216
-0
Tests/Unit/iTasks/UI/Layout/UnitTests.icl
Tests/Unit/iTasks/UI/Layout/UnitTests.icl
+51
-1
No files found.
Tests/Unit/iTasks.UI.Editor.Generic.UnitTests.prj.default
0 → 100644
View file @
80c2f191
Version: 1.4
Global
ProjectRoot: .
Target: StdEnv
Exec: {Project}*iTasks.UI.Editor.Generic.UnitTests
CodeGen
CheckStacks: False
CheckIndexes: True
Application
HeapSize: 20971520
StackSize: 512000
ExtraMemory: 8192
IntialHeapSize: 204800
HeapSizeMultiplier: 4096
ShowExecutionTime: False
ShowGC: False
ShowStackSize: False
MarkingCollector: False
DisableRTSFlags: False
StandardRuntimeEnv: True
Profile
Memory: False
MemoryMinimumHeapSize: 0
Time: False
Stack: False
Dynamics: True
GenericFusion: False
DescExL: False
Output
Output: NoConsole
Font: Monaco
FontSize: 9
WriteStdErr: False
Link
LinkMethod: Static
GenerateRelocations: False
GenerateSymbolTable: False
GenerateLinkMap: False
LinkResources: False
ResourceSource:
GenerateDLL: False
ExportedNames:
Paths
Path: {Project}
Path: {Project}*..*..*Libraries
Path: {Application}*lib*Dynamics
Path: {Application}*lib*GraphCopy
Path: {Application}*lib*Sapl
Path: {Application}*lib*StdEnv
Path: {Application}*lib*TCPIP
Path: {Application}*lib*Platform
Path: {Application}*lib*Platform*Deprecated*StdLib
Precompile:
Postlink:
MainModule
Name: iTasks.UI.Editor.Generic.UnitTests
Dir: {Project}
Compiler
NeverMemoryProfile: False
NeverTimeProfile: False
StrictnessAnalysis: True
ListTypes: StrictExportTypes
ListAttributes: True
Warnings: True
Verbose: True
ReadableABC: False
ReuseUniqueNodes: True
Fusion: False
Tests/Unit/iTasks/UI/Editor/Generic/UnitTests.icl
0 → 100644
View file @
80c2f191
module
iTasks
.
UI
.
Editor
.
Generic
.
UnitTests
import
iTasks
.
UI
.
Editor
.
Generic
import
iTasks
.
Util
.
Testing
import
qualified
Data
.
Map
as
DM
//Unfortunately the javascript linker introduces
//the need to carry the iworld around in editors
import
iTasks
.
Internal
.
IWorld
from
iTasks
.
Engine
import
defaultEngineOptions
derive
gPrint
LUI
,
LUIChanges
,
LUIEffects
,
LUIEffectStage
,
LUINo
,
Set
,
UI
,
UIType
,
JSONNode
,
Map
derive
gPrint
MaybeError
,
Maybe
,
UIChange
,
UIChildChange
,
UIAttributeChange
derive
gPrint
EditMask
,
FieldMask
tests
=
flatten
[
primitiveEditorTests
,
compositeEditorTests
]
primitiveEditorTests
=
flatten
[
intEditorTests
,
realEditorTests
,
charEditorTests
,
boolEditorTests
,
stringEditorTests
]
compositeEditorTests
=
flatten
[
adtEditorTests
,
recordEditorTests
,
tupleEditorTests
]
//For different types consider:
//- Generate the initial UI (mandatory and optional editors)
//- Process different types of events (mandatory and optional editors)
//- Refresh with different values (mandatory and optional editors)
//- Consider different edit modes
intEditorTests
=
[
genRequiredIntUI
,
genOptionalIntUI
]
genRequiredIntUI
=
assertEqualWorld
"Generate UI for Editor of type Int"
(
Ok
(
UI
UIIntegerField
('
DM
'.
fromList
[(
"hint-type"
,
JSONString
"info"
)
,(
"editorId"
,
JSONString
"v"
)
,(
"hint"
,
JSONString
"Please enter a whole number (this value is required)"
)
,(
"optional"
,
JSONBool
False
)
,(
"mode"
,
JSONString
"enter"
)
,(
"taskId"
,
JSONString
"4-2"
)
,(
"value"
,
JSONNull
)
]
)
[]
,
FieldMask
{
touched
=
False
,
valid
=
False
,
state
=
JSONNull
}))
(
genUIWrapper
[]
0
Enter
intEditor
)
where
intEditor
::
Editor
Int
intEditor
=
gEditor
{|*|}
genOptionalIntUI
=
assertEqualWorld
"Generate UI for Editor of type Maybe Int"
(
Ok
(
UI
UIIntegerField
('
DM
'.
fromList
[(
"hint-type"
,
JSONString
"info"
)
,(
"editorId"
,
JSONString
"v"
)
,(
"hint"
,
JSONString
"Please enter a whole number"
)
,(
"optional"
,
JSONBool
True
)
,(
"mode"
,
JSONString
"enter"
)
,(
"taskId"
,
JSONString
"4-2"
)
,(
"value"
,
JSONNull
)
]
)
[]
,
FieldMask
{
touched
=
False
,
valid
=
True
,
state
=
JSONNull
}))
(
genUIWrapper
[]
Nothing
Enter
intEditor
)
where
intEditor
::
Editor
(
Maybe
Int
)
intEditor
=
gEditor
{|*|}
realEditorTests
=
[]
charEditorTests
=
[]
boolEditorTests
=
[]
stringEditorTests
=
[]
::
EnumADT
=
ACons
|
BCons
|
CCons
::
GroupADT
=
GroupCons
Int
Int
::
RecursiveADT
=
NilCons
|
RecCons
RecursiveADT
::
MixedADT
=
MixedGroupA
Int
String
|
MixedSimpleA
|
MixedGroupB
Bool
derive
gEditor
EnumADT
,
GroupADT
,
RecursiveADT
,
MixedADT
derive
gDefault
RecursiveADT
adtEditorTests
=
[]
::
TwoFieldRecord
=
{
fieldA
::
String
,
fieldB
::
Int
}
derive
gEditor
TwoFieldRecord
derive
gPrint
TwoFieldRecord
derive
gEq
TwoFieldRecord
recordEditorTests
=
[
genRequiredTwoFieldRecordUI
,
editRequiredTwoFieldRecord
]
genRequiredTwoFieldRecordUI
=
assertEqualWorld
"Generate UI for Editor of type TwoFieldRecord"
(
Ok
(
UI
UIRecord
'
DM
'.
newMap
[
UI
UITextField
('
DM
'.
fromList
[(
"hint-type"
,
JSONString
"info"
)
,(
"editorId"
,
JSONString
"v0"
)
,(
"hint"
,
JSONString
"Please enter a single line of text (this value is required)"
)
,(
"optional"
,
JSONBool
False
)
,(
"mode"
,
JSONString
"enter"
)
,(
"taskId"
,
JSONString
"4-2"
)
,(
"value"
,
JSONNull
)
,(
"label"
,
JSONString
"fieldA"
)
,(
"minlength"
,
JSONInt
1
)
]
)
[]
,
UI
UIIntegerField
('
DM
'.
fromList
[(
"hint-type"
,
JSONString
"info"
)
,(
"editorId"
,
JSONString
"v1"
)
,(
"hint"
,
JSONString
"Please enter a whole number (this value is required)"
)
,(
"optional"
,
JSONBool
False
)
,(
"mode"
,
JSONString
"enter"
)
,(
"taskId"
,
JSONString
"4-2"
)
,(
"value"
,
JSONNull
)
,(
"label"
,
JSONString
"fieldB"
)
]
)
[]
]
,
CompoundMask
[
FieldMask
{
touched
=
False
,
valid
=
False
,
state
=
JSONNull
}
,
FieldMask
{
touched
=
False
,
valid
=
False
,
state
=
JSONNull
}
]
)
)
(
genUIWrapper
[]
{
fieldA
=
""
,
fieldB
=
0
}
Enter
editor
)
where
editor
::
Editor
TwoFieldRecord
editor
=
gEditor
{|*|}
editRequiredTwoFieldRecord
=
assertEqualWorld
"Edit UI for Editor of type TwoFieldRecord"
((
Ok
(
postChange
,
CompoundMask
[
FieldMask
{
touched
=
True
,
valid
=
True
,
state
=
JSONString
"x"
}
,
FieldMask
{
touched
=
False
,
valid
=
False
,
state
=
JSONNull
}
]
)
,{
fieldA
=
"x"
,
fieldB
=
0
}
)
)
(
onEditWrapper
[]
edit
preValue
preMask
Enter
editor
)
where
editor
::
Editor
TwoFieldRecord
editor
=
gEditor
{|*|}
edit
=
([
0
],
JSONString
"x"
)
preValue
=
{
fieldA
=
""
,
fieldB
=
0
}
preMask
=
CompoundMask
[
FieldMask
{
touched
=
False
,
valid
=
False
,
state
=
JSONNull
}
,
FieldMask
{
touched
=
False
,
valid
=
False
,
state
=
JSONNull
}
]
postChange
=
ChangeUI
[]
[
(
0
,
ChangeChild
(
ChangeUI
[
SetAttribute
"value"
(
JSONString
"x"
)
,
SetAttribute
"hint"
(
JSONString
"You have correctly entered a single line of text"
)
,
SetAttribute
"hint-type"
(
JSONString
"valid"
)
]
[]
)
)
]
postValue
=
{
fieldA
=
"x"
,
fieldB
=
0
}
postMask
=
CompoundMask
[
FieldMask
{
touched
=
True
,
valid
=
True
,
state
=
JSONString
"x"
}
,
FieldMask
{
touched
=
False
,
valid
=
False
,
state
=
JSONNull
}
]
tupleEditorTests
=
[]
genUIWrapper
datapath
value
mode
editor
world
#
(
options
,
world
)
=
defaultEngineOptions
world
#
iworld
=
createIWorld
options
world
#
vst
=
{
taskId
=
"4-2"
,
mode
=
mode
,
optional
=
False
,
selectedConsIndex
=
0
,
iworld
=
iworld
}
#
(
res
,{
VSt
|
iworld
={
IWorld
|
world
}})
=
editor
.
genUI
datapath
value
vst
=
(
res
,
world
)
onEditWrapper
datapath
edit
preValue
preMask
mode
editor
world
#
(
options
,
world
)
=
defaultEngineOptions
world
#
iworld
=
createIWorld
options
world
#
vst
=
{
taskId
=
"4-2"
,
mode
=
mode
,
optional
=
False
,
selectedConsIndex
=
0
,
iworld
=
iworld
}
#
(
res
,
postValue
,{
VSt
|
iworld
={
IWorld
|
world
}})
=
editor
.
Editor
.
onEdit
datapath
edit
preValue
preMask
vst
=
((
res
,
postValue
),
world
)
Start
w
=
runUnitTests
tests
w
Tests/Unit/iTasks/UI/Layout/UnitTests.icl
View file @
80c2f191
...
...
@@ -306,6 +306,7 @@ extractDownstreamChangeTests =
,
extractDownstreamChangeTest_ChangeInChildrenWithMoves
,
extractDownstreamChangeTest_NewWrappedChild
,
extractDownstreamChangeTest_NoLongerWrappedChild
,
extractDownstreamChangeTest_ChangingAWrappedAttribute
,
extractDownstreamChangeTest_NewUnwrappedChild
,
extractDownstreamChangeTest_NoLongerUnwrappedChild
,
extractDownstreamChangeTest_ChangingAnUnwrappedAttribute
...
...
@@ -841,6 +842,30 @@ extractDownstreamChangeTest_NoLongerWrappedChild =
]
noChanges
noEffects
,
initLUIMoves
))
extractDownstreamChangeTest_ChangingAWrappedAttribute
=
assertEqual
"Changing an attribute of a wrapped child"
(
ChangeUI
[]
[(
1
,
ChangeChild
(
ChangeUI
[]
[(
0
,
ChangeChild
(
ChangeUI
[
SetAttribute
"value"
(
JSONInt
42
)]
[]))]))]
,(
LUINode
UIPanel
('
DM
'.
fromList
[(
"title"
,
JSONString
"Parent panel"
)])
[
LUINode
UIInteract
'
DM
'.
newMap
[]
noChanges
noEffects
,
LUINode
UIStep
'
DM
'.
newMap
[
LUINode
UIInteract
('
DM
'.
fromList
[(
"value"
,
JSONInt
42
)])
[]
noChanges
noEffects
]
noChanges
{
noEffects
&
wrapper
=
ESApplied
(
LUINo
[
0
])}
,
LUINode
UIParallel
'
DM
'.
newMap
[]
noChanges
noEffects
]
noChanges
noEffects
,
initLUIMoves
)
)
(
extractDownstreamChange
(
LUINode
UIPanel
('
DM
'.
fromList
[(
"title"
,
JSONString
"Parent panel"
)])
[
LUINode
UIInteract
'
DM
'.
newMap
[]
noChanges
noEffects
,
LUINode
UIStep
'
DM
'.
newMap
[
LUINode
UIInteract
'
DM
'.
newMap
[]
{
noChanges
&
setAttributes
=
'
DM
'.
fromList
[(
"value"
,
JSONInt
42
)]}
noEffects
]
noChanges
{
noEffects
&
wrapper
=
ESApplied
(
LUINo
[
0
])}
,
LUINode
UIParallel
'
DM
'.
newMap
[]
noChanges
noEffects
]
noChanges
noEffects
,
initLUIMoves
))
extractDownstreamChangeTest_NewUnwrappedChild
=
assertEqual
"New unwrapped child"
(
ChangeUI
[]
[(
1
,
ChangeChild
(
ReplaceUI
(
UI
UIDebug
'
DM
'.
newMap
[])))]
...
...
@@ -1442,7 +1467,21 @@ wrapUITests =
]
noChanges
noEffects
,
initLUIMoves
)
)
,
assertEqual
"Wrap ui: check stability (no change)"
(
LUINode
UIStep
('
DM
'.
fromList
[(
"title"
,
JSONString
"A"
)])
[
LUINode
UIInteract
'
DM
'.
newMap
[]
noChanges
noEffects
,
LUINode
UIParallel
'
DM
'.
newMap
[]
noChanges
noEffects
,
LUINode
UIStep
'
DM
'.
newMap
[]
noChanges
noEffects
]
noChanges
{
noEffects
&
wrapper
=
ESApplied
(
LUINo
[
0
])}
,
initLUIMoves
)
(
wrapUI
UIStep
(
LUINo
[
0
])
(
LUINode
UIStep
('
DM
'.
fromList
[(
"title"
,
JSONString
"A"
)])
[
LUINode
UIInteract
'
DM
'.
newMap
[]
noChanges
noEffects
,
LUINode
UIParallel
'
DM
'.
newMap
[]
noChanges
noEffects
,
LUINode
UIStep
'
DM
'.
newMap
[]
noChanges
noEffects
]
noChanges
{
noEffects
&
wrapper
=
ESApplied
(
LUINo
[
0
])}
,
initLUIMoves
)
)
]
unwrapUITests
=
...
...
@@ -1553,6 +1592,17 @@ layoutSubUIsTests =
]
{
noChanges
&
delAttributes
=
'
DS
'.
fromList
[
"title"
]}
noEffects
,
initLUIMoves
)
)
,
assertEqual
"Layout sub-uis rule: stability of wrapped node (no change)"
(
LUINode
UIDebug
'
DM
'.
newMap
[
LUINode
UITextField
'
DM
'.
newMap
[]
noChanges
noEffects
]
noChanges
{
noEffects
&
wrapper
=
ESApplied
(
LUINo
[
0
])}
,
initLUIMoves
)
(
layoutSubUIs
(
SelectByType
UITextField
)
(
wrapUI
UIDebug
)
(
LUINo
[
0
])
(
LUINode
UIDebug
'
DM
'.
newMap
[
LUINode
UITextField
'
DM
'.
newMap
[]
noChanges
noEffects
]
noChanges
{
noEffects
&
wrapper
=
ESApplied
(
LUINo
[
0
])}
,
initLUIMoves
)
)
]
combinationTests
=
//Applying the first change
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a 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