@@ -28,16 +28,26 @@ fun NodeData.toJson() : String {
28
28
29
29
internal fun assertAllNodesConformToSpec (expectedRoot : NodeData , actualRoot : INode ) {
30
30
val originalIdToNode = actualRoot.getDescendants(false ).associateBy { it.originalId() }
31
- assertNodeConformsToSpec(expectedRoot, actualRoot)
31
+ val originalIdToSpec = buildSpecIndex(expectedRoot)
32
+ assertNodeConformsToSpec(expectedRoot, actualRoot, originalIdToSpec)
32
33
for (expectedChild in expectedRoot.children) {
33
34
val actualChild = originalIdToNode[expectedChild.originalId()] ? : fail(" expected child has no id" )
34
- assertNodeConformsToSpec(expectedChild, actualChild)
35
+ assertNodeConformsToSpec(expectedChild, actualChild, originalIdToSpec )
35
36
}
36
37
}
37
38
38
- internal fun assertNodeConformsToSpec (expected : NodeData , actual : INode ) {
39
+ private fun buildSpecIndex (nodeData : NodeData ) : Map <String , NodeData > {
40
+ val map = mutableMapOf<String , NodeData >()
41
+ nodeData.originalId()?.let { map[it] = nodeData}
42
+ nodeData.children.forEach {
43
+ map.putAll(buildSpecIndex(it))
44
+ }
45
+ return map
46
+ }
47
+
48
+ internal fun assertNodeConformsToSpec (expected : NodeData , actual : INode , originalIdToSpec : Map <String , NodeData > = emptyMap()) {
39
49
assertNodePropertiesConformToSpec(expected, actual)
40
- assertNodeReferencesConformToSpec(expected, actual)
50
+ assertNodeReferencesConformToSpec(expected, actual, originalIdToSpec )
41
51
assertNodeChildOrderConformsToSpec(expected, actual)
42
52
}
43
53
@@ -47,13 +57,28 @@ internal fun assertNodePropertiesConformToSpec(expected: NodeData, actual: INode
47
57
assertEquals(expected.id, actualProperties[NodeData .idPropertyKey])
48
58
}
49
59
50
- internal fun assertNodeReferencesConformToSpec (expected : NodeData , actual : INode ) {
51
- val actualReferences = actual.getReferenceRoles().associateWithNotNull {
52
- actual.getReferenceTarget(it)?.let { node ->
53
- node.getPropertyValue(NodeData .idPropertyKey) ? : node.reference.serialize()
60
+ internal fun assertNodeReferencesConformToSpec (
61
+ expected : NodeData ,
62
+ actual : INode ,
63
+ originalIdToSpec : Map <String , NodeData > = emptyMap()
64
+ ) {
65
+ var numUnresolvableRefs = 0
66
+
67
+ val actualResolvableRefs = actual.getReferenceRoles().associateWithNotNull {
68
+ val target = actual.getReferenceTarget(it)
69
+ if (target == null ) {
70
+ numUnresolvableRefs++
71
+ return @associateWithNotNull null
54
72
}
73
+ target.getPropertyValue(NodeData .idPropertyKey) ? : target.reference.serialize()
74
+ }
75
+
76
+ assertEquals(expected.references.size, actualResolvableRefs.size + numUnresolvableRefs)
77
+ assert (expected.references.entries.containsAll(actualResolvableRefs.entries))
78
+ val unresolved = expected.references.entries.subtract(actualResolvableRefs.entries)
79
+ unresolved.forEach {
80
+ assert (! originalIdToSpec.containsKey(it.value)) { " node ref with target ${it.value} should have been resolved" }
55
81
}
56
- assertEquals(expected.references, actualReferences)
57
82
}
58
83
59
84
internal fun assertNodeChildOrderConformsToSpec (expected : NodeData , actual : INode ) {
0 commit comments