Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[#68] Add control to ensure we do not defined twice the same attribut…
…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
Showing
6 changed files
with
100 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
src/main/scala/definiti/core/validation/controls/AttributeTypeUniquenessControl.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
} | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
src/test/resources/samples/controls/attributeTypeUniqueness/distinctDefinedTypes.def
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
type Travel { | ||
id: String as Id | ||
} | ||
|
||
type Fly { | ||
id: String as Id | ||
} |
5 changes: 5 additions & 0 deletions
5
src/test/resources/samples/controls/attributeTypeUniqueness/duplicated.def
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
type Travel { | ||
id: String as Id | ||
source: String as Location | ||
destination: String as Location | ||
} |
5 changes: 5 additions & 0 deletions
5
src/test/resources/samples/controls/attributeTypeUniqueness/nominal.def
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
type Travel { | ||
id: String as Id | ||
source: String as Source | ||
destination: String as Destination | ||
} |
41 changes: 41 additions & 0 deletions
41
src/test/scala/definiti/core/end2end/controls/AttributeTypeUniquenessControlSpec.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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") | ||
} | ||
|