Skip to content

Commit

Permalink
[#68] Add control to ensure we do not defined twice the same attribut…
Browse files Browse the repository at this point in the history
…e type name

Each attribute type name must be unique.
So we add a control to ensure it.

This commit does the following:

* Add a control verifying the attribute type name uniqueness
* Add tests verifying the new control
  • Loading branch information
Gaëtan Rizio committed Aug 11, 2018
1 parent 0772ecb commit eae0113
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/main/scala/definiti/core/validation/Controls.scala
Expand Up @@ -20,6 +20,7 @@ object Controls {
lazy val all: Seq[Control[Root]] = Seq(
AliasTypeTypeControl,
AttributeTypeControl,
AttributeTypeUniquenessControl,
CalculatorOperandsAreNumberControl,
EnumerationUniquenessControl,
ComparisonOnSameTypeControl,
Expand Down
@@ -0,0 +1,41 @@
package definiti.core.validation.controls

import definiti.common.ast._
import definiti.common.control.{Control, ControlLevel, ControlResult}
import definiti.common.validation.Alert

private[core] object AttributeTypeUniquenessControl extends Control[Root] {
override val description: String = "Check if there is no several attribute types with the same name"
override val defaultLevel: ControlLevel.Value = ControlLevel.error

override def control(root: Root, library: Library): ControlResult = {
ControlResult.squash {
library.definedTypes.map(controlDefinedType(_, library))
}
}

private def controlDefinedType(definedType: DefinedType, library: Library): ControlResult = {
ControlResult.squash {
definedType.attributes.zipWithIndex.map { case (attribute, index) =>
attribute.typeName match {
case Some(typeName) =>
val indexOfAttribute = definedType.attributes.indexWhere(_.typeName.contains(typeName))
if (indexOfAttribute != index) {
val otherAttribute = definedType.attributes(indexOfAttribute)
ControlResult(errorSameName(typeName, attribute.location, otherAttribute.location))
} else {
OK
}
case None =>
OK
}
}
}
}

def errorSameName(conflictName: String, location1: Location, location2: Location): Seq[Alert] = {
Seq(location1, location2).map { location =>
alert(s"The attribute type name ${conflictName} is used at least twice", location)
}
}
}
@@ -0,0 +1,7 @@
type Travel {
id: String as Id
}

type Fly {
id: String as Id
}
@@ -0,0 +1,5 @@
type Travel {
id: String as Id
source: String as Location
destination: String as Location
}
@@ -0,0 +1,5 @@
type Travel {
id: String as Id
source: String as Source
destination: String as Destination
}
@@ -0,0 +1,41 @@
package definiti.core.end2end.controls

import definiti.common.ast.Root
import definiti.common.program.Ko
import definiti.common.tests.{ConfigurationMock, LocationPath}
import definiti.core.ProgramResultMatchers._
import definiti.core.end2end.EndToEndSpec
import definiti.core.validation.controls.AttributeTypeUniquenessControl

class AttributeTypeUniquenessControlSpec extends EndToEndSpec {

import AttributeTypeUniquenessControlSpec._

"Project.generatePublicAST" should "validate a defined type with several attribute types with different names" in {
val output = processFile("controls.attributeTypeUniqueness.nominal", configuration)
output shouldBe ok[Root]
}

it should "invalidate a defined type with two attribute types with the same name" in {
val output = processFile("controls.attributeTypeUniqueness.duplicated", configuration)
output should beResult(Ko[Root](
AttributeTypeUniquenessControl.errorSameName(
"Location",
duplicatedLocation(3, 3, 29),
duplicatedLocation(4, 3, 34)
)
))
}

it should "validate two defined types with one attribute type each having the same name" in {
val output = processFile("controls.attributeTypeUniqueness.distinctDefinedTypes", configuration)
output shouldBe ok[Root]
}
}

object AttributeTypeUniquenessControlSpec {
val configuration = ConfigurationMock().withOnlyControls(AttributeTypeUniquenessControl)

val duplicatedLocation = LocationPath.control(AttributeTypeUniquenessControl, "duplicated")
}

0 comments on commit eae0113

Please sign in to comment.