How to test model-wise Non-Typesystem rule?
Hi!
I have a root concept named "Page". It extends "AbstractRoot".
I also have a Non-Typesystem rule that there may not be two roots with the same name:
Now I'm trying to test this feature.
So I created a solution named "tests" and created a model in it, named "tests@tests".
I imported my language, "baseLanguage.unitTest", and "mps.lang.test".
Then I created new "NodesTestCase" that looks like this:
But this test fails, cuz there's no error.
It seems that two pages created in the test are not in the same model.
What I do wrong?
Is it possible to test cross-node rules?
Thanks in advance!
P.S.
I already have a similar test case for two stories with the same name in one page,
and it passes. So all imports seems to be fine.
I have a root concept named "Page". It extends "AbstractRoot".
I also have a Non-Typesystem rule that there may not be two roots with the same name:
check_Root_has_unique_name_in_model
if (root.parent.isNull) {
root.model.roots(INamedConcept).forEach({~it =>
if (it != root && it.name.equals(root.name)) {
error String.format("There's already a %s element with this name!", it.concept.getName()) -> root;
}
});
}
Now I'm trying to test this feature.
So I created a solution named "tests" and created a model in it, named "tests@tests".
I imported my language, "baseLanguage.unitTest", and "mps.lang.test".
Then I created new "NodesTestCase" that looks like this:
But this test fails, cuz there's no error.
It seems that two pages created in the test are not in the same model.
What I do wrong?
Is it possible to test cross-node rules?
Thanks in advance!
P.S.
I already have a similar test case for two stories with the same name in one page,
and it passes. So all imports seems to be fine.
Please sign in to leave a comment.

Vaclav
So, it is possible to test the feature if I rewrite it to look for all nodes, and not only roots? )
I think I could rewrite the rule so it would look for all nodes, instead of only roots, and then it would explicitly filter out the nodes that shouldn't be checked (for example, I have a "story" concept that may be both a root and a page child, but it should be checked only if it's a root). But I fear it will overcomplicate with time, or I'll just forgot to add some new "exception" to the rule.
Is there currently any way to mark tested nodes to be treated as roots?
if (root.ancestor<concept = AbstractRoot>.isNull) {
...
It works now )
I finally remembered about "Node Explorer" and this thing helps immensely )
So yeah, I've changed rule to look like this:
if (root.ancestor<concept = AbstractRoot>.isNull) { root.model.nodes(AbstractRoot).forEach({~it => if (it != root && it.name :eq: root.name) { error String.format("There's already a %s element with this name!", it.concept.getName()) -> root; } }); }So now it checks any "my root" that isn't part of another "my root".
Only need to remember now that any concept that will be compiled as separate java class should extend my "AbstractRoot".
Thanks again!
I also had to add filter for iterated nodes in the model.
So top "abstract roots" is compared only to other top "abstract roots":
if (root.ancestor<concept = AbstractRoot>.isNull) { root.model.nodes(AbstractRoot).where({~it => it.ancestor<concept = AbstractRoot>.isNull; }).forEach({~it => if (it != root && it.name :eq: root.name) { error String.format("There's already a %s element with this name!", it.concept.getName()) -> root; } }); }Now it works perfectly )