diff --git a/app.hypermedia.testing.dsl/src/main/java/app/hypermedia/testing/dsl/HydraRuntimeModule.xtend b/app.hypermedia.testing.dsl/src/main/java/app/hypermedia/testing/dsl/HydraRuntimeModule.xtend index bd7c58f..15f3c25 100644 --- a/app.hypermedia.testing.dsl/src/main/java/app/hypermedia/testing/dsl/HydraRuntimeModule.xtend +++ b/app.hypermedia.testing.dsl/src/main/java/app/hypermedia/testing/dsl/HydraRuntimeModule.xtend @@ -10,7 +10,7 @@ import org.eclipse.xtext.conversion.IValueConverterService * Use this class to register components to be used at runtime / without the Equinox extension registry. */ class HydraRuntimeModule extends AbstractHydraRuntimeModule { - override Class bindIValueConverterService() { + override Class bindIValueConverterService() { return HydraValueConverterService } } diff --git a/app.hypermedia.testing.dsl/src/main/java/app/hypermedia/testing/dsl/validation/HydraValidator.xtend b/app.hypermedia.testing.dsl/src/main/java/app/hypermedia/testing/dsl/validation/HydraValidator.xtend index e875fac..cb1877c 100644 --- a/app.hypermedia.testing.dsl/src/main/java/app/hypermedia/testing/dsl/validation/HydraValidator.xtend +++ b/app.hypermedia.testing.dsl/src/main/java/app/hypermedia/testing/dsl/validation/HydraValidator.xtend @@ -3,6 +3,15 @@ */ package app.hypermedia.testing.dsl.validation +import app.hypermedia.testing.dsl.hydra.HydraPackage +import org.eclipse.xtext.validation.Check +import java.net.URI +import app.hypermedia.testing.dsl.hydra.NamespaceDeclaration +import app.hypermedia.testing.dsl.core.CorePackage +import java.net.URISyntaxException +import app.hypermedia.testing.dsl.core.ClassBlock +import app.hypermedia.testing.dsl.hydra.OperationBlock +import app.hypermedia.testing.dsl.hydra.RelaxedOperationBlock /** * This class contains custom validation rules. @@ -10,16 +19,49 @@ package app.hypermedia.testing.dsl.validation * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#validation */ class HydraValidator extends AbstractHydraValidator { - -// public static val INVALID_NAME = 'invalidName' -// -// @Check -// def checkGreetingStartsWithCapital(Greeting greeting) { -// if (!Character.isUpperCase(greeting.name.charAt(0))) { -// warning('Name should start with a capital', -// HydraPackage.Literals.GREETING__NAME, -// INVALID_NAME) -// } -// } - + static final String INVALID_URI = 'Value is not a valid URI' + + @Check + def checkValidUri(NamespaceDeclaration ns) { + if (tryParseUri(ns.namespace) === false) { + error(INVALID_URI, + HydraPackage.Literals.NAMESPACE_DECLARATION__NAMESPACE) + } + } + + @Check + def checkValidUri(ClassBlock clas) { + if (tryParseUri(clas.name.value) === false) { + error(INVALID_URI, + CorePackage.Literals.CLASS_BLOCK__NAME + ) + } + } + + @Check + def checkValidUri(OperationBlock clas) { + if (tryParseUri(clas.name.value) === false) { + error(INVALID_URI, + HydraPackage.Literals.OPERATION_BLOCK__NAME + ) + } + } + + @Check + def checkValidUri(RelaxedOperationBlock clas) { + if (tryParseUri(clas.name.value) === false) { + error(INVALID_URI, + HydraPackage.Literals.RELAXED_OPERATION_BLOCK__NAME + ) + } + } + + private def tryParseUri(String uri) { + try { + val parsed = new URI(uri) + return parsed.scheme !== null + } catch(URISyntaxException e) { + return false + } + } } diff --git a/app.hypermedia.testing.dsl/src/test/java/app/hypermedia/testing/dsl/tests/hydra/ClassParsingTest.xtend b/app.hypermedia.testing.dsl/src/test/java/app/hypermedia/testing/dsl/tests/hydra/ClassParsingTest.xtend new file mode 100644 index 0000000..cc90665 --- /dev/null +++ b/app.hypermedia.testing.dsl/src/test/java/app/hypermedia/testing/dsl/tests/hydra/ClassParsingTest.xtend @@ -0,0 +1,51 @@ +/* + * generated by Xtext 2.18.0 + */ +package app.hypermedia.testing.dsl.tests.hydra + +import app.hypermedia.testing.dsl.core.CorePackage +import app.hypermedia.testing.dsl.hydra.HydraScenario +import app.hypermedia.testing.dsl.tests.HydraInjectorProvider +import com.google.inject.Inject +import org.eclipse.xtext.testing.InjectWith +import org.eclipse.xtext.testing.extensions.InjectionExtension +import org.eclipse.xtext.testing.util.ParseHelper +import org.eclipse.xtext.testing.validation.ValidationTestHelper +import org.junit.jupiter.api.^extension.ExtendWith +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.MethodSource + +@ExtendWith(InjectionExtension) +@InjectWith(HydraInjectorProvider) +class ClassParsingTest { + @Inject extension ParseHelper + @Inject extension ValidationTestHelper + + @ParameterizedTest + @MethodSource("app.hypermedia.testing.dsl.tests.hydra.TestCases#invalidUris") + def void classWithInvalidUri_failsValidation(String id) { + // when + val result = ''' + With Class <«id»> { } + '''.parse + + // then + result.assertError( + CorePackage.Literals.CLASS_BLOCK, + null, + "Value is not a valid URI" + ) + } + + @ParameterizedTest + @MethodSource("app.hypermedia.testing.dsl.tests.hydra.TestCases#validUris") + def void classWithValidUri_passesValidation(String id) { + // when + val result = ''' + With Class <«id»> { } + '''.parse + + // then + result.assertNoIssues() + } +} diff --git a/app.hypermedia.testing.dsl/src/test/java/app/hypermedia/testing/dsl/tests/hydra/OperationParsingTest.xtend b/app.hypermedia.testing.dsl/src/test/java/app/hypermedia/testing/dsl/tests/hydra/OperationParsingTest.xtend index d5b8ce0..f81b714 100644 --- a/app.hypermedia.testing.dsl/src/test/java/app/hypermedia/testing/dsl/tests/hydra/OperationParsingTest.xtend +++ b/app.hypermedia.testing.dsl/src/test/java/app/hypermedia/testing/dsl/tests/hydra/OperationParsingTest.xtend @@ -18,12 +18,17 @@ import app.hypermedia.testing.dsl.tests.TestHelpers import app.hypermedia.testing.dsl.core.ClassBlock import app.hypermedia.testing.dsl.Modifier import app.hypermedia.testing.dsl.hydra.RelaxedOperationBlock +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.MethodSource +import org.eclipse.xtext.testing.validation.ValidationTestHelper +import app.hypermedia.testing.dsl.hydra.HydraPackage @ExtendWith(InjectionExtension) @InjectWith(HydraInjectorProvider) class OperationParsingTest { - @Inject + @Inject extension ParseHelper parseHelper + @Inject extension ValidationTestHelper @Test def void withOperationOnTopLevel_ParsesName() { @@ -133,4 +138,60 @@ class OperationParsingTest { assertThat(operationBlock).isInstanceOf(OperationBlock) assertThat(operationBlock.modifier).isEqualTo(Modifier.WITH) } + + @ParameterizedTest + @MethodSource("app.hypermedia.testing.dsl.tests.hydra.TestCases#invalidUris") + def void topOperationWithInvalidUri_failsValidation(String id) { + // when + val result = ''' + With Operation <«id»> { } + '''.parse + + // then + result.assertError( + HydraPackage.Literals.RELAXED_OPERATION_BLOCK, + null, + "Value is not a valid URI" + ) + } + + @ParameterizedTest + @MethodSource("app.hypermedia.testing.dsl.tests.hydra.TestCases#validUris") + def void topOperationWithValidUri_passesValidation(String id) { + // when + val result = ''' + With Class <«id»> { } + '''.parse + + // then + result.assertNoIssues() + } + + @ParameterizedTest + @MethodSource("app.hypermedia.testing.dsl.tests.hydra.TestCases#invalidUris") + def void operationWithInvalidUri_failsValidation(String id) { + // when + val result = ''' + With Class some:class { With Operation <«id»> {} } + '''.parse + + // then + result.assertError( + HydraPackage.Literals.OPERATION_BLOCK, + null, + "Value is not a valid URI" + ) + } + + @ParameterizedTest + @MethodSource("app.hypermedia.testing.dsl.tests.hydra.TestCases#validUris") + def void oeprationWithValidUri_passesValidation(String id) { + // when + val result = ''' + With Class some:class { With Operation <«id»> {} } + '''.parse + + // then + result.assertNoIssues() + } } diff --git a/app.hypermedia.testing.dsl/src/test/java/app/hypermedia/testing/dsl/tests/hydra/PrefixParsingTest.xtend b/app.hypermedia.testing.dsl/src/test/java/app/hypermedia/testing/dsl/tests/hydra/PrefixParsingTest.xtend index 550e2c8..46b94e3 100644 --- a/app.hypermedia.testing.dsl/src/test/java/app/hypermedia/testing/dsl/tests/hydra/PrefixParsingTest.xtend +++ b/app.hypermedia.testing.dsl/src/test/java/app/hypermedia/testing/dsl/tests/hydra/PrefixParsingTest.xtend @@ -14,11 +14,16 @@ import app.hypermedia.testing.dsl.tests.HydraInjectorProvider import app.hypermedia.testing.dsl.tests.TestHelpers import app.hypermedia.testing.dsl.hydra.NamespaceDeclaration import org.junit.jupiter.api.Test +import org.eclipse.xtext.testing.validation.ValidationTestHelper +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.MethodSource +import app.hypermedia.testing.dsl.hydra.HydraPackage @ExtendWith(InjectionExtension) @InjectWith(HydraInjectorProvider) class PrefixParsingTest { @Inject extension ParseHelper + @Inject extension ValidationTestHelper @Test def void prefix_parsesSuccesfully() { @@ -34,4 +39,32 @@ class PrefixParsingTest { assertThat(namespaceDeclaration.prefix.value).isEqualTo('foaf') assertThat(namespaceDeclaration.namespace).isEqualTo('http://xmlns.com/foaf/0.1/') } + + @ParameterizedTest + @MethodSource("app.hypermedia.testing.dsl.tests.hydra.TestCases#invalidUris") + def void prefixWithInvalidUri_failsValidation(String value) { + // when + val result = ''' + PREFIX "foaf": <«value»> + '''.parse + + // then + result.assertError( + HydraPackage.Literals.NAMESPACE_DECLARATION, + null, + "Value is not a valid URI" + ) + } + + @ParameterizedTest + @MethodSource("app.hypermedia.testing.dsl.tests.hydra.TestCases#validUris") + def void prefixWithValidUri_passesValidation(String value) { + // when + val result = ''' + PREFIX "foaf": <«value»> + '''.parse + + // then + result.assertNoIssues() + } } diff --git a/app.hypermedia.testing.dsl/src/test/java/app/hypermedia/testing/dsl/tests/hydra/TestCases.xtend b/app.hypermedia.testing.dsl/src/test/java/app/hypermedia/testing/dsl/tests/hydra/TestCases.xtend new file mode 100644 index 0000000..1cf9af6 --- /dev/null +++ b/app.hypermedia.testing.dsl/src/test/java/app/hypermedia/testing/dsl/tests/hydra/TestCases.xtend @@ -0,0 +1,18 @@ +package app.hypermedia.testing.dsl.tests.hydra + +class TestCases { + static def validUris() { + return #[ + "http://xmlns.com/foaf/0.1/", + "urn:valid:urn", + "mailto:dsl@example.com" + ] + } + + static def invalidUris() { + return #[ + "not-a-URI", + "12345" + ] + } +} \ No newline at end of file