Current section
Files
Jump to
Current section
Files
lib/testing/conformance_test_suite/composite_properties.ex
defmodule Paradigm.Conformance.TestSuite.CompositeProperties do
defmacro __using__(_opts) do
quote do
test "validates composite property constraints" do
paradigm = %Paradigm{
classes: %{
"container" => %Paradigm.Class{
name: "Container",
properties: %{
"compositeParts" => %Paradigm.Property{
name: "compositeParts",
is_composite: true,
lower_bound: 1,
upper_bound: :infinity,
type: "part"
}
}
},
"part" => %Paradigm.Class{
name: "Part",
properties: %{}
}
}
}
part1 = %Paradigm.Graph.Node{
id: "part1",
class: "part",
owned_by: "container1",
data: %{}
}
part2 = %Paradigm.Graph.Node{
id: "part2",
class: "part",
owned_by: "container1",
data: %{}
}
container = %Paradigm.Graph.Node{
id: "container1",
class: "container",
data: %{
"compositeParts" => [
%Paradigm.Graph.Node.Ref{id: "part1", composite: true},
%Paradigm.Graph.Node.Ref{id: "part2", composite: true}
]
}
}
graph =
build_graph(part1)
|> Paradigm.Graph.insert_node(part2)
|> Paradigm.Graph.insert_node(container)
Paradigm.Conformance.assert_conforms(graph, paradigm)
end
test "detects composite property with primitive type" do
paradigm = %Paradigm{
primitive_types: %{"string" => %Paradigm.PrimitiveType{name: "String"}},
classes: %{
"class1" => %Paradigm.Class{
name: "TestClass",
properties: %{
"invalidComposite" => %Paradigm.Property{
name: "invalidComposite",
is_composite: true,
type: "string",
upper_bound: 2
}
}
}
}
}
node = %Paradigm.Graph.Node{
id: "node1",
class: "class1",
data: %{"invalidComposite" => ["value1", "value2"]}
}
graph = build_graph(node)
assert %Paradigm.Conformance.Result{
issues: [
%Paradigm.Conformance.Issue{
property: "invalidComposite",
kind: :composite_primitive_type,
details: %{type: "string"},
node_id: "node1"
}
]
} = Paradigm.Conformance.check_graph(graph, paradigm)
end
test "validates composite ownership exclusivity" do
paradigm = %Paradigm{
classes: %{
"container1" => %Paradigm.Class{
name: "Container1",
properties: %{
"parts" => %Paradigm.Property{
name: "parts",
is_composite: true,
lower_bound: 0,
upper_bound: :infinity,
type: "part"
}
}
},
"container2" => %Paradigm.Class{
name: "Container2",
properties: %{
"parts" => %Paradigm.Property{
name: "parts",
is_composite: true,
lower_bound: 0,
upper_bound: :infinity,
type: "part"
}
}
},
"part" => %Paradigm.Class{
name: "Part",
properties: %{}
}
}
}
# Same part referenced by two composite properties (should fail)
part1 = %Paradigm.Graph.Node{
id: "part1",
class: "part",
data: %{},
owned_by: "container1"
}
container1 = %Paradigm.Graph.Node{
id: "container1",
class: "container1",
data: %{"parts" => [%Paradigm.Graph.Node.Ref{id: "part1", composite: true}]}
}
container2 = %Paradigm.Graph.Node{
id: "container2",
class: "container2",
data: %{"parts" => [%Paradigm.Graph.Node.Ref{id: "part1", composite: true}]}
}
graph =
build_graph(part1)
|> Paradigm.Graph.insert_node(container1)
|> Paradigm.Graph.insert_node(container2)
assert %Paradigm.Conformance.Result{
issues: [
%Paradigm.Conformance.Issue{
property: "parts",
kind: :multiple_composite_owners,
node_id: "container1"
}
]
} = Paradigm.Conformance.check_graph(graph, paradigm)
end
test "detects composite property without composite reference flag" do
paradigm = %Paradigm{
classes: %{
"container" => %Paradigm.Class{
name: "Container",
properties: %{
"parts" => %Paradigm.Property{
name: "parts",
is_composite: true,
lower_bound: 1,
upper_bound: :infinity,
type: "part"
}
}
},
"part" => %Paradigm.Class{
name: "Part",
properties: %{}
}
}
}
# Composite property but reference lacks composite: true flag
part1 = %Paradigm.Graph.Node{
id: "part1",
class: "part",
data: %{},
owned_by: "container1"
}
container = %Paradigm.Graph.Node{
id: "container1",
class: "container",
data: %{"parts" => [%Paradigm.Graph.Node.Ref{id: "part1", composite: false}]}
}
graph =
build_graph(part1)
|> Paradigm.Graph.insert_node(container)
assert %Paradigm.Conformance.Result{
issues: [
%Paradigm.Conformance.Issue{
property: "parts",
kind: :composite_reference_without_flag,
details: %{referenced_id: "part1"},
node_id: "container1"
}
]
} = Paradigm.Conformance.check_graph(graph, paradigm)
end
test "detects node missing owned_by flag in composite relationship" do
paradigm = %Paradigm{
classes: %{
"container" => %Paradigm.Class{
name: "Container",
properties: %{
"parts" => %Paradigm.Property{
name: "parts",
is_composite: true,
lower_bound: 1,
upper_bound: :infinity,
type: "part"
}
}
},
"part" => %Paradigm.Class{
name: "Part",
properties: %{}
}
}
}
# Node is owned in composite relationship but lacks owned_by field
part1 = %Paradigm.Graph.Node{id: "part1", class: "part", data: %{}, owned_by: nil}
container = %Paradigm.Graph.Node{
id: "container1",
class: "container",
data: %{"parts" => [%Paradigm.Graph.Node.Ref{id: "part1", composite: true}]}
}
graph =
build_graph(part1)
|> Paradigm.Graph.insert_node(container)
assert %Paradigm.Conformance.Result{
issues: [
%Paradigm.Conformance.Issue{
property: "parts",
kind: :composite_owned_node_without_owner,
details: %{owner_node_id: "container1"},
node_id: "part1"
}
]
} = Paradigm.Conformance.check_graph(graph, paradigm)
end
test "validates correct composite relationship with proper flags" do
paradigm = %Paradigm{
classes: %{
"container" => %Paradigm.Class{
name: "Container",
properties: %{
"parts" => %Paradigm.Property{
name: "parts",
is_composite: true,
lower_bound: 1,
upper_bound: :infinity,
type: "part"
}
}
},
"part" => %Paradigm.Class{
name: "Part",
properties: %{}
}
}
}
# Both composite flag on reference and owned_by flag on node are set correctly
part1 = %Paradigm.Graph.Node{
id: "part1",
class: "part",
data: %{},
owned_by: "container1"
}
container = %Paradigm.Graph.Node{
id: "container1",
class: "container",
data: %{"parts" => [%Paradigm.Graph.Node.Ref{id: "part1", composite: true}]}
}
graph = build_graph([part1, container])
Paradigm.Conformance.assert_conforms(graph, paradigm)
end
end
end
end