1 | xquery version "1.0"; |
---|
2 | (:~~~~~~~~~~~~~~~~~~~~~~~~~~ Conformance Test ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
3 | Test Number: 012 |
---|
4 | Description: Assert uniqueness of sequenceNumber across all attributes |
---|
5 | and association ends of class. |
---|
6 | Reference: |
---|
7 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~:) |
---|
8 | |
---|
9 | import module namespace mod-fr = "urn:local-module:ISO19136-V3.2-AnxE_XMI-V1.1:framework" |
---|
10 | at "#{ROOT_URL}ISO19136-AnxE/modules/module-framework-functions.xq"; |
---|
11 | |
---|
12 | import module namespace mod-xp = "urn:local-module:ISO19136-V3.2-AnxE_XMI-V1.1:xmi-proc" |
---|
13 | at "#{ROOT_URL}ISO19136-AnxE/modules/module-xproc-functions.xq"; |
---|
14 | |
---|
15 | declare namespace UML = "omg.org/UML1.3"; |
---|
16 | declare namespace cr = "http://ndg.service.newmoon.conftest-result/1.0"; |
---|
17 | |
---|
18 | (: Declare local variables, particular to this test :) |
---|
19 | declare variable $test-num as xs:integer := 12; |
---|
20 | declare variable $pass-msg as xs:string := "Each "sequenceNumber" tagged value is unique in the scope of the class owning the property."; |
---|
21 | declare variable $fail-msg as xs:string := "The model contains non-unique sequenceNumber as follow:"; |
---|
22 | |
---|
23 | (: Declare the local assert function which defines a postive condition for pass :) |
---|
24 | declare function local:assert($doc-root as node()?) as node()? |
---|
25 | { |
---|
26 | let $fail := ( |
---|
27 | for $class in $doc-root//UML:Class |
---|
28 | let $seq := local:get-class-sequence-numbers($class) |
---|
29 | for $dup in mod-xp:get-duplicates($seq/@value) |
---|
30 | return |
---|
31 | for $el in $seq[@value eq $dup] |
---|
32 | let $nodename := string(node-name($el/../..)) |
---|
33 | return |
---|
34 | <cr:message> |
---|
35 | { |
---|
36 | (: Display descriptive error information :) |
---|
37 | if ($nodename eq "UML:Attribute") then |
---|
38 | concat("The sequenceNumber="", $el/@value, "" for attribute "", $el/../../@name, "" on class "", $class/@name, "" duplicates another sequence number in the same scope.") |
---|
39 | else |
---|
40 | concat("The sequenceNumber="", $el/@value, "" for association end with rolename "", $el/../../@name, "" from class "", $class/@name, "" duplicates another sequence number in the same scope.") |
---|
41 | } |
---|
42 | </cr:message> |
---|
43 | ) |
---|
44 | return |
---|
45 | if (empty($fail)) then () |
---|
46 | else |
---|
47 | <cr:fail> |
---|
48 | <cr:messages>{ $fail }</cr:messages> |
---|
49 | </cr:fail> |
---|
50 | }; |
---|
51 | |
---|
52 | (: Retrieve all sequenceNumber tagged values which belong to the class' attributes and association ends :) |
---|
53 | declare function local:get-class-sequence-numbers($class as node()) as node()* |
---|
54 | { |
---|
55 | (: Retrieve sequenceNumber tagged values of attributes of the class :) |
---|
56 | $class//UML:Attribute//UML:TaggedValue[@tag eq "sequenceNumber"], |
---|
57 | |
---|
58 | (: Retrieve sequenceNumber tagged values of association ends of the class :) |
---|
59 | //UML:Association//UML:AssociationEnd[ |
---|
60 | (preceding-sibling::* | following-sibling::*)[@type eq $class/@xmi.id] and |
---|
61 | .//UML:TaggedValue[ |
---|
62 | @tag[matches(., "^(dest|source)style$")] and |
---|
63 | ( |
---|
64 | @value[contains(., "Navigable=Navigable;")] or |
---|
65 | count(ancestor::UML:Association.connection//UML:AssociationEnd) eq |
---|
66 | count(ancestor::UML:Association.connection//UML:AssociationEnd//UML:TaggedValue[@tag[matches(., "^(dest|source)style$")] and @value[contains(., "Navigable=Unspecified;")]]) |
---|
67 | ) |
---|
68 | ] |
---|
69 | ]//UML:TaggedValue[@tag eq "sequenceNumber"] |
---|
70 | }; |
---|
71 | |
---|
72 | (: Create a new result element :) |
---|
73 | mod-fr:new-result($test-num, $pass-msg, $fail-msg, local:assert(/)) |
---|