/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.isis.core.metamodel.facets.param.parameter; import java.lang.reflect.Method; import java.util.List; import java.util.regex.Pattern; import org.jmock.Expectations; import org.jmock.auto.Mock; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.apache.isis.applib.annotation.Optionality; import org.apache.isis.applib.annotation.Parameter; import org.apache.isis.applib.spec.Specification; import org.apache.isis.core.metamodel.facets.AbstractFacetFactoryJUnit4TestCase; import org.apache.isis.core.metamodel.facets.FacetFactory; import org.apache.isis.core.metamodel.facets.objectvalue.mandatory.MandatoryFacet; import org.apache.isis.core.metamodel.facets.objectvalue.maxlen.MaxLengthFacet; import org.apache.isis.core.metamodel.facets.objectvalue.mustsatisfyspec.MustSatisfySpecificationFacet; import org.apache.isis.core.metamodel.facets.objectvalue.regex.RegExFacet; import org.apache.isis.core.metamodel.facets.param.parameter.mandatory.MandatoryFacetForParameterAnnotation; import org.apache.isis.core.metamodel.facets.param.parameter.maxlen.MaxLengthFacetForParameterAnnotation; import org.apache.isis.core.metamodel.facets.param.parameter.mustsatisfy.MustSatisfySpecificationFacetForParameterAnnotation; import org.apache.isis.core.metamodel.facets.param.parameter.regex.RegExFacetForParameterAnnotation; import org.apache.isis.core.metamodel.spec.ObjectSpecification; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; public class ParameterAnnotationFacetFactoryTest extends AbstractFacetFactoryJUnit4TestCase { ParameterAnnotationFacetFactory facetFactory; Method actionMethod; @Mock ObjectSpecification mockTypeSpec; @Mock ObjectSpecification mockReturnTypeSpec; void expectRemoveMethod(final Method actionMethod) { context.checking(new Expectations() {{ oneOf(mockMethodRemover).removeMethod(actionMethod); }}); } void allowingLoadSpecificationRequestsFor(final Class<?> cls, final Class<?> returnType) { context.checking(new Expectations() {{ allowing(mockSpecificationLoader).loadSpecification(cls); will(returnValue(mockTypeSpec)); allowing(mockSpecificationLoader).loadSpecification(returnType); will(returnValue(mockReturnTypeSpec)); }}); } @Before public void setUp() throws Exception { facetFactory = new ParameterAnnotationFacetFactory(); facetFactory.setServicesInjector(mockServicesInjector); } @After public void tearDown() throws Exception { facetFactory = null; } public static class MaxLength extends ParameterAnnotationFacetFactoryTest { @Test public void withAnnotation() { class Customer { public void someAction( @Parameter( maxLength = 30 ) final String name) { } } // given actionMethod = findMethod(Customer.class, "someAction", new Class[]{String.class} ); // when final FacetFactory.ProcessParameterContext processParameterContext = new FacetFactory.ProcessParameterContext(Customer.class, actionMethod, 0, null, facetedMethodParameter); facetFactory.processParams(processParameterContext); // then final MaxLengthFacet maxLengthFacet = facetedMethodParameter.getFacet(MaxLengthFacet.class); Assert.assertNotNull(maxLengthFacet); Assert.assertTrue(maxLengthFacet instanceof MaxLengthFacetForParameterAnnotation); assertThat(maxLengthFacet.value(), is(30)); } } public static class MustSatisfy extends ParameterAnnotationFacetFactoryTest { public static class NotTooHot implements Specification { @Override public String satisfies(final Object obj) { return null; } } public static class NotTooCold implements Specification { @Override public String satisfies(final Object obj) { return null; } } @Test public void withAnnotation() { class Customer { public void someAction( @Parameter( mustSatisfy = {NotTooHot.class, NotTooCold.class} ) final String name ) { } } // given actionMethod = findMethod(Customer.class, "someAction", new Class[]{String.class} ); // expecting context.ignoring(mockServicesInjector); // when final FacetFactory.ProcessParameterContext processParameterContext = new FacetFactory.ProcessParameterContext(Customer.class, actionMethod, 0, null, facetedMethodParameter); facetFactory.processParams(processParameterContext); // then final MustSatisfySpecificationFacet mustSatisfySpecificationFacet = facetedMethodParameter.getFacet(MustSatisfySpecificationFacet.class); Assert.assertNotNull(mustSatisfySpecificationFacet); Assert.assertTrue(mustSatisfySpecificationFacet instanceof MustSatisfySpecificationFacetForParameterAnnotation); MustSatisfySpecificationFacetForParameterAnnotation mustSatisfySpecificationFacetImpl = (MustSatisfySpecificationFacetForParameterAnnotation) mustSatisfySpecificationFacet; List<Specification> specifications = mustSatisfySpecificationFacetImpl.getSpecifications(); assertThat(specifications.size(), is(2)); assertTrue(specifications.get(0) instanceof NotTooHot); assertTrue(specifications.get(1) instanceof NotTooCold); } } public static class Mandatory extends ParameterAnnotationFacetFactoryTest { @Test public void whenOptionalityIsTrue() { class Customer { public void someAction( @Parameter( optionality = Optionality.OPTIONAL ) final String name ) { } } // given actionMethod = findMethod(Customer.class, "someAction", new Class[]{String.class} ); // when final FacetFactory.ProcessParameterContext processParameterContext = new FacetFactory.ProcessParameterContext(Customer.class, actionMethod, 0, null, facetedMethodParameter); facetFactory.processParams(processParameterContext); // then final MandatoryFacet mandatoryFacet = facetedMethodParameter.getFacet(MandatoryFacet.class); Assert.assertNotNull(mandatoryFacet); Assert.assertTrue(mandatoryFacet instanceof MandatoryFacetForParameterAnnotation.Optional); } @Test public void whenOptionalityIsFalse() { class Customer { public void someAction( @Parameter( optionality = Optionality.MANDATORY ) final String name ) { } } // given actionMethod = findMethod(Customer.class, "someAction", new Class[]{String.class} ); // when final FacetFactory.ProcessParameterContext processParameterContext = new FacetFactory.ProcessParameterContext(Customer.class, actionMethod, 0, null, facetedMethodParameter); facetFactory.processParams(processParameterContext); // then final MandatoryFacet mandatoryFacet = facetedMethodParameter.getFacet(MandatoryFacet.class); Assert.assertNotNull(mandatoryFacet); Assert.assertTrue(mandatoryFacet instanceof MandatoryFacetForParameterAnnotation.Required); } @Test public void whenOptionalityIsDefault() { class Customer { public void someAction( @Parameter( optionality = Optionality.DEFAULT ) final String name ) { } } // given actionMethod = findMethod(Customer.class, "someAction", new Class[]{String.class} ); // when final FacetFactory.ProcessParameterContext processParameterContext = new FacetFactory.ProcessParameterContext(Customer.class, actionMethod, 0, null, facetedMethodParameter); facetFactory.processParams(processParameterContext); // then final MandatoryFacet mandatoryFacet = facetedMethodParameter.getFacet(MandatoryFacet.class); Assert.assertNull(mandatoryFacet); } @Test public void whenNone() { class Customer { public void someAction( final String name ) { } } // given actionMethod = findMethod(Customer.class, "someAction", new Class[]{String.class} ); // when final FacetFactory.ProcessParameterContext processParameterContext = new FacetFactory.ProcessParameterContext(Customer.class, actionMethod, 0, null, facetedMethodParameter); facetFactory.processParams(processParameterContext); // then final MandatoryFacet mandatoryFacet = facetedMethodParameter.getFacet(MandatoryFacet.class); Assert.assertNull(mandatoryFacet); } } public static class RegEx extends ParameterAnnotationFacetFactoryTest { @Test public void whenHasAnnotation() { class Customer { public void someAction( @Parameter( regexPattern = "[123].*", regexPatternFlags = Pattern.CASE_INSENSITIVE | Pattern.MULTILINE ) final String name ) { } } // given actionMethod = findMethod(Customer.class, "someAction", new Class[]{String.class} ); // when final FacetFactory.ProcessParameterContext processParameterContext = new FacetFactory.ProcessParameterContext(Customer.class, actionMethod, 0, null, facetedMethodParameter); facetFactory.processParams(processParameterContext); // then final RegExFacet regExFacet = facetedMethodParameter.getFacet(RegExFacet.class); Assert.assertNotNull(regExFacet); Assert.assertTrue(regExFacet instanceof RegExFacetForParameterAnnotation); assertThat(regExFacet.caseSensitive(), is(false)); assertThat(regExFacet.validation(), is("[123].*")); } @Test public void whenNone() { class Customer { public void someAction( @Parameter( ) final String name ) { } } // given actionMethod = findMethod(Customer.class, "someAction", new Class[]{String.class} ); // when final FacetFactory.ProcessParameterContext processParameterContext = new FacetFactory.ProcessParameterContext(Customer.class, actionMethod, 0, null, facetedMethodParameter); facetFactory.processParams(processParameterContext); // then final RegExFacet regExFacet = facetedMethodParameter.getFacet(RegExFacet.class); Assert.assertNull(regExFacet); } @Test public void whenEmptyString() { class Customer { public void someAction( @Parameter( regexPattern = "" ) final String name ) { } } // given actionMethod = findMethod(Customer.class, "someAction", new Class[]{String.class} ); // when final FacetFactory.ProcessParameterContext processParameterContext = new FacetFactory.ProcessParameterContext(Customer.class, actionMethod, 0, null, facetedMethodParameter); facetFactory.processParams(processParameterContext); // then final RegExFacet regExFacet = facetedMethodParameter.getFacet(RegExFacet.class); Assert.assertNull(regExFacet); } @Test public void whenNotAnnotatedOnStringParameter() { class Customer { public void someAction( @Parameter( regexPattern = "[123].*" ) final int name ) { } } // given actionMethod = findMethod(Customer.class, "someAction", new Class[]{int.class} ); // when final FacetFactory.ProcessParameterContext processParameterContext = new FacetFactory.ProcessParameterContext(Customer.class, actionMethod, 0, null, facetedMethodParameter); facetFactory.processParams(processParameterContext); // then final RegExFacet regExFacet = facetedMethodParameter.getFacet(RegExFacet.class); Assert.assertNull(regExFacet); } } }