Commit f2c9790e authored by Philip Makedonski's avatar Philip Makedonski
Browse files

+ compatibility updates to constraints

parent a4bf849d
Loading
Loading
Loading
Loading
+59 −40
Original line number Diff line number Diff line
@@ -304,7 +304,7 @@ context VariableUse {
//	}
//Local variables of tester components only
	constraint VariableUseComponentRole {
		check:  self.componentInstance.type.variable->contains(self.variable)  
		check:  self.componentInstance.debugCheck() and self.componentInstance.type.variable->contains(self.variable)  
			and self.componentInstance.role.name = 'Tester'
		message: self.prefix()+"All variables used in a 'DataUse' specification via a 'VariableUse' shall be local to the same 'componentInstance' and the 'componentInstance' shall be in the role 'Tester'."
	}
@@ -528,6 +528,13 @@ context BoundedLoopBehaviour {
//Iteration number shall be countable and positive
//  The expression assigned to the 'numIteration' property shall evaluate to a countable 'SimpleDataInstance' of an arbitrary user-defined data type, e.g. a positive Integer value.


//Single numIteration in totally ordered test description
	constraint SingleTotalIterationCount {
	    check: self.getParentTestDescription().isLocallyOrdered 
	    	or self.numIteration->size() = 1
    	message: self.prefix()+"If the 'BoundedLoopBehaviour' is contained in a totally ordered 'TestDescription' then there shall be exactly one numIteration."
	}
}


@@ -646,7 +653,7 @@ context Assertion {
//Constraints
//Boolean condition
	constraint AssertionOtherwise {
		check:  self.condition.getDataType().name = 'Boolean'
		check: self.condition.debugCheck() and self.condition.getDataType().name = 'Boolean'
		message: self.prefix()+"The 'condition' shall evaluate to predefined 'DataType' 'Boolean'."
	}
//Otherwise of type 'Verdict'
@@ -657,7 +664,8 @@ context Assertion {

}

context Interaction {
//TODO:split for message and procedure
context Message {
//Constraints
//Gate references of an interaction shall be different
//	constraint DistinctInteractionGates {
@@ -712,8 +720,9 @@ context Interaction {
//Matching data type for 'argument' and 'variable'
	constraint InteractionArgumentAndVariableType {
		check:  self.target.forAll(t | 
					t.variable.oclIsUndefined()
				 or t.variable.dataType = self.argument.getDataType()) 
					t.valueAssignment.oclIsUndefined() 
				 or not t.valueAssignment.variable.oclIsUndefined() and t.valueAssignment.variable.dataType = self.argument.getDataType())
				 //TODO: add parameters? 
		message: self.prefix()+"The 'DataUse' specification of the 'argument' and the referenced 'Variable' of any 'Target' shall refer to the same 'DataType'."
	}

@@ -730,13 +739,13 @@ context Target {
//Constraints
//Variable and target gate of the same component instance
	constraint TargetComponent {
		check:  self.variable.oclIsUndefined() 
			 or self.targetGate.component.type.variable->contains(self.variable)
		check:  self.valueAssignment.oclIsUndefined() 
			 or self.targetGate.component.type.variable->contains(self.valueAssignment.variable)
		message: self.prefix()+"The referenced 'Variable' shall exist in the same 'ComponentType' as the 'GateInstance' that is referred to by the 'GateReference' of the 'targetGate'."
	}
//Variable of a tester component only
	constraint TargetVariableComponentRole {
		check:  self.variable.oclIsUndefined() 
		check:  self.valueAssignment.oclIsUndefined() 
			 or self.targetGate.component.role.name = 'Tester'
		message: self.prefix()+"If a 'Variable' is specified, the 'ComponentInstance' referenced by 'targetGate' shall be in the role 'Tester'."
	}
@@ -747,26 +756,36 @@ context TestDescriptionReference {
//Constraints
//Number of actual parameters
	constraint ParameterCount {
		//TODO: this is utterly broken
		check:  self.actualParameter->size() = self.testDescription.formalParameter->size()
		message: self.prefix()+"The number of actual parameters in the 'TestDescriptionReference' shall be equal to the number of formal parameters of the referenced 'TestDescription'."
	}

//No use of variables in actual parameters
	constraint NoVariables {
		//TODO: this is utterly broken -> should be argument and treated as parameter binding -> so in the implementation it is still actualParameter...
		//TODO: test..
		//TODO: need better / faster testing..
//		check: 	self.actualParameter.forAll(p | not p.dataUse.oclIsKindOf(VariableUse))
				//and p.argument->forAll(a | not a.dataUse.oclIsKindOf(VariableUse))
//		 		and self.argument->closure(a | a.dataUse.argument)->forAll(a | not a.dataUse.oclIsKindOf(VariableUse))
		check: 	self.actualParameter.forAll(p | 
					not p.oclIsKindOf(VariableUse)
				and p.argument->forAll(a | not a.dataUse.oclIsKindOf(VariableUse))
		 		and p.argument->closure(a | a.dataUse.argument)->forAll(a | not a.dataUse.oclIsKindOf(VariableUse)))
					not p.dataUse.oclIsKindOf(VariableUse)
				and p.dataUse.argument->forAll(a | not a.dataUse.oclIsKindOf(VariableUse))
		 		and p.dataUse.argument->closure(a | a.dataUse.argument)->forAll(a | not a.dataUse.oclIsKindOf(VariableUse)))
		 		 
		message: self.prefix()+"The 'DataUse' expressions used to describe actual parameters shall not contain variables directly or indirectly."
	}

//Matching parameters
	constraint TestDescriptionParameters {
		check:  self.actualParameter.forAll(ap |
					self.testDescription.formalParameter->size() > self.actualParameter->indexOf(ap) 
				and ap.getDataType() = self.testDescription.formalParameter->at(self.actualParameter.indexOf(ap)).dataType)
		message: self.prefix()+"The actual parameter AP[i] of index i in the ordered list of 'actualParameter's shall match 'DataType' of the 'FormalParameter' FP[i] of index i in the ordered list of formal parameters of the referenced 'TestDescription'."
		//TODO: this is utterly broken
//		check:  self.actualParameter.forAll(ap |
//					self.testDescription.formalParameter->size() > self.actualParameter->indexOf(ap) 
//				and ap.getDataType() = self.testDescription.formalParameter->at(self.actualParameter.indexOf(ap)).dataType)
				//Types are checked in ParameterBinding	
		check:  self.testDescription.formalParameter->forAll(p | self.actualParameter->exists(a | a.parameter = p))
		message: self.prefix()+"For each 'FormalParameter' defined in 'formalParameter' of the referenced 'TestDescription' there shall be a 'ParameterBinding' in 'argument' that refers to that 'FormalParameter' in 'parameter'."
	}

//Restriction to 1:1 component instance bindings
@@ -857,9 +876,12 @@ context ActionReference {
//Constraints
//Matching parameters
	constraint ActionParameters {
		check:  self.actualParameter->forAll(ap | 
					ap.getDataType() = self.action.formalParameter->at(self.actualParameter->indexOf(ap)).dataType) 
		message: self.prefix()+"The actual parameter AP[i] of index i in the ordered set of 'actualParameter's shall match the 'DataType' of the 'FormalParameter' FP[i] of index i in the ordered set of formal parameters of the referenced 'Action'."
		//TODO: same problem as test description reference
//		check:  self.actualParameter->forAll(ap | 
//					ap.getDataType() = self.action.formalParameter->at(self.actualParameter->indexOf(ap)).dataType) 
		//TODO: exists vs includes?
		check:  self.action.formalParameter->forAll(p | self.actualParameter->exists(a | a.parameter = p))
		message: self.prefix()+"For each 'FormalParameter' defined in 'formalParameter of' the referenced 'Action' there shall be a 'ParameterBinding' in 'argument' that refers to that 'FormalParameter' in 'parameter'."
	}

}
@@ -874,7 +896,7 @@ context Assignment {
	}
//Matching data type
	constraint AssignmentDataType {
		check:  self.expression.getDataType() = self.variable.dataType
		check:  self.expression.getDataType() = self.variable.variable.dataType
		message: self.prefix()+"The provided 'DataUse' expression shall match the 'DataType' of the referenced 'Variable'."
	}
}
@@ -885,23 +907,20 @@ context Assignment {
//	  - the latter already covered by the constraint under GateReference


//TODO: why is this duplicated?! (and outdated)






context Assignment {
//Constraints
//Known component instance
	constraint AssignmentComponent {
		//TODO: update syntax? current syntax flexibility allows validation!
		check:  not self.componentInstance.oclIsUndefined()
		message: self.prefix()+"The property 'componentInstance' shall be set to identify the 'Variable' in this 'Assignment'."
	}
//Matching data type
	constraint AssignmentDataType {
		check:  self.expression.getDataType() = self.variable.dataType
		message: self.prefix()+"The provided 'DataUse' expression shall match the 'DataType' of the referenced 'Variable'."
	}
}
//
//context Assignment {
////Constraints
////Known component instance
//	constraint AssignmentComponent {
//		//TODO: update syntax? current syntax flexibility allows validation!
//		check:  not self.componentInstance.oclIsUndefined()
//		message: self.prefix()+"The property 'componentInstance' shall be set to identify the 'Variable' in this 'Assignment'."
//	}
////Matching data type
//	constraint AssignmentDataType {
//		check:  self.expression.getDataType() = self.variable.dataType
//		message: self.prefix()+"The provided 'DataUse' expression shall match the 'DataType' of the referenced 'Variable'."
//	}
//}
+37 −0
Original line number Diff line number Diff line
@@ -104,10 +104,47 @@ operation TDL!DataInstanceUse getDataType() : Any {
	}
}

operation TDL!DataElementUse getDataType() : Any {
	if (not self.dataElement.oclIsUndefined()) {
		//TODO: consider extracting into resolveDataType or similar
		//TODO: consider using the resolveDataType from the model?
		//("Start: "+self.dataElement).println();
		if (self.dataElement.oclIsKindOf(DataInstance)) {
			return self.dataElement.dataType;
		} else if (self.dataElement.oclIsKindOf(DataType)) {
			return self.dataElement;
		} else if (self.dataElement.oclIsKindOf(Function)) {
			return self.dataElement.returnType; 
		} else if (self.dataElement.oclIsKindOf(FormalParameter)) {
			return self.dataElement.dataType; 
		} else {
			//why is this called on AnnotationType?!
			(self.dataElement+".getDataType() not yet defined").println();
//			(self.dataElement.type+".getDataType() not yet defined").println();
//			(self.dataElement.type.name+".getDataType() not yet defined").println();
		}
		//TODO: extract
	} else {
		if (self.container().oclIsTypeOf(MemberAssignment)) {
			return self.container().member.dataType;
		} else if (self.container().oclIsTypeOf(ParameterBinding)) {
			return self.container().parameter.dataType;
		} else {
			(self.container().type.name+".getDataType() not yet defined").println();
		}
	}
}


operation TDL!FunctionCall getDataType() : Any {
	return self.`function`.returnType;
}

operation TDL!PredefinedFunctionCall getDataType() : Any {
	return self.`function`.returnType;
}


operation TDL!VariableUse getDataType() : Any {
	return self.variable.dataType;
}
+5 −0
Original line number Diff line number Diff line
@@ -3,6 +3,11 @@ operation Any prefix() : String {
	return self.type().name+":  "+self.qualifiedName() + " ";
}

operation Any debugCheck() : Boolean {
	("  DEBUG: "+self).println();
	return true;
}

operation Any debugAnnotations() : Boolean {
	self.println();
	("  Annotations: "+self.annotation).println();