Commit 80c2f191 authored by Bas Lijnse's avatar Bas Lijnse

Added unit tests to reproduce bug in composition of layout rules.

parent 7d5cb944
Pipeline #12978 failed with stage
in 10 minutes and 4 seconds
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
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
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment