blob: d7978547167b28454c9221516adec58a453c1a29 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2017 Christian W. Damus and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Christian W. Damus - initial API and implementation
******************************************************************************/
package org.eclipse.emfforms.common.internal.validation;
import static org.hamcrest.CoreMatchers.both;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertSame;
import static org.junit.Assume.assumeThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyMapOf;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.Set;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.DiagnosticChain;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EValidator;
import org.eclipse.emf.ecore.EValidator.SubstitutionLabelProvider;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.util.EObjectValidator;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.emfstore.bowling.BowlingFactory;
import org.eclipse.emf.emfstore.bowling.BowlingPackage;
import org.eclipse.emf.emfstore.bowling.League;
import org.eclipse.emf.emfstore.bowling.Player;
import org.eclipse.emf.emfstore.bowling.util.BowlingValidator;
import org.eclipse.emfforms.common.spi.validation.exception.ValidationCanceledException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
/**
* Test cases for the {@link ValidationServiceImpl} class.
*
* @author Christian W. Damus
*/
@SuppressWarnings("nls")
@RunWith(MockitoJUnitRunner.class)
public class ValidationServiceImpl_Test {
private final ValidationServiceImpl fixture = new ValidationServiceImpl();
/**
* Initializes me.
*/
public ValidationServiceImpl_Test() {
super();
}
/**
* Verify that the service's {@link SubstitutionLabelProvider} is used for
* the construction of the "Diagnosis of ..." messages in the diagnostic chains.
*
* @see <a href="http://eclip.se/526224">bug 526224</a>
*/
@Test
public void labelsInDiagnosticChains() {
final SubstitutionLabelProvider labels = mock(SubstitutionLabelProvider.class);
when(labels.getObjectLabel(any(EObject.class))).thenReturn("The league");
final League league = BowlingFactory.eINSTANCE.createLeague();
league.setName("Narnian First Division");
fixture.setSubstitutionLabelProvider(labels);
final Diagnostic diagnostic = fixture.validate(league);
assertThat("SubstitutionLabelProvider not used to create diagnostic chain message",
diagnostic.getMessage(),
containsString("The league"));
}
/**
* Verify that the service can create diagnostic chains even without
* a {@link SubstitutionLabelProvider}.
*
* @see <a href="http://eclip.se/526224">bug 526224</a>
*/
@Test
public void diagnosticChainsNoSubstitutionLabelProvider() {
final League league = BowlingFactory.eINSTANCE.createLeague();
league.setName("Narnian First Division");
final Diagnostic diagnostic = fixture.validate(league);
assertThat("Invalid diagnostic chain message",
diagnostic.getMessage(),
// The EcoreUtil::getIdentifier API was used
both(containsString("#//")).and(containsString("LeagueImpl")));
}
/**
* Verify that the service uses a single shared validation context map when validating
* multiple objects.
*
* @see <a href="http://eclip.se/526224">bug 526224</a>
*/
@Test
public void sharedValidationContext() throws ValidationCanceledException {
final Set<Object> validationContexts = Collections.newSetFromMap(new IdentityHashMap<Object, Boolean>());
// Fake up a validator that gathers validation context maps
final EValidator validator = mock(EValidator.class);
when(validator.validate(any(EClass.class), any(EObject.class), any(DiagnosticChain.class),
anyMapOf(Object.class, Object.class))).then(new Answer<Boolean>() {
@Override
public Boolean answer(InvocationOnMock invocation) throws Throwable {
validationContexts.add(invocation.getArguments()[3]);
return false;
}
});
// Add it to the registry
final EValidator oldValidator = EValidator.Registry.INSTANCE.getEValidator(BowlingPackage.eINSTANCE);
EValidator.Registry.INSTANCE.put(BowlingPackage.eINSTANCE, validator);
try {
final League league = BowlingFactory.eINSTANCE.createLeague();
league.setName("Narnian First Division");
final Player p1 = BowlingFactory.eINSTANCE.createPlayer();
p1.setName("Mr Tumnus");
league.getPlayers().add(p1);
final Player p2 = BowlingFactory.eINSTANCE.createPlayer();
p2.setName("Mr Tumnus");
league.getPlayers().add(p2);
// Validate the entire contents
fixture.validate(EcoreUtil.<EObject> getAllContents(Collections.singleton(league)));
} finally {
// Restore the real validator
EValidator.Registry.INSTANCE.put(BowlingPackage.eINSTANCE, oldValidator);
}
assumeThat("No validation occurred", validationContexts.size(), not(0));
assertThat("Too many validation contexts", validationContexts.size(), is(1));
}
@Test
public void diagnosticValidateUsesExistingCustomValidator() {
final EPackage ePackage = EcoreFactory.eINSTANCE.createEPackage();
final EClass extendedPlayerClass = EcoreFactory.eINSTANCE.createEClass();
extendedPlayerClass.setName("ExtendedPlayer");
extendedPlayerClass.getESuperTypes().add(BowlingPackage.eINSTANCE.getPlayer());
ePackage.setName("extendedPlayerPackage");
ePackage.setNsPrefix("extendedPlayerPackage");
ePackage.setNsURI("extendedPlayerPackage");
ePackage.getEClassifiers().add(extendedPlayerClass);
final EObject extendedPlayer = EcoreUtil.create(extendedPlayerClass);
extendedPlayer.eSet(BowlingPackage.eINSTANCE.getPlayer_Height(), 20d);
final EValidator validatorForEObject = fixture.getEValidatorForEObject(extendedPlayer);
final BasicDiagnostic diagnostic = new BasicDiagnostic();
validatorForEObject.validate(extendedPlayerClass, extendedPlayer, diagnostic, null);
assertSame(Diagnostic.ERROR, diagnostic.getSeverity());
assertSame(2, diagnostic.getChildren().size());
assertSame(EObjectValidator.DIAGNOSTIC_SOURCE, diagnostic.getChildren().get(0).getSource());
assertSame(BowlingPackage.eINSTANCE.getPlayer_EMails(), diagnostic.getChildren().get(0).getData().get(1));
assertSame(BowlingValidator.DIAGNOSTIC_SOURCE, diagnostic.getChildren().get(1).getSource());
assertSame(BowlingPackage.eINSTANCE.getPlayer_Height(), diagnostic.getChildren().get(1).getData().get(1));
}
@Test
public void diagnosticValidateUsesDefaultValidator() {
final EPackage ePackage = EcoreFactory.eINSTANCE.createEPackage();
final EClass myClass = EcoreFactory.eINSTANCE.createEClass();
myClass.setName("MyClass");
final EAttribute nameAttribute = EcoreFactory.eINSTANCE.createEAttribute();
nameAttribute.setName("name");
nameAttribute.setEType(EcorePackage.eINSTANCE.getEString());
nameAttribute.setLowerBound(1);
myClass.getEStructuralFeatures().add(nameAttribute);
ePackage.setName("standalone");
ePackage.setNsPrefix("standalone");
ePackage.setNsURI("standalone");
ePackage.getEClassifiers().add(myClass);
final EObject my = EcoreUtil.create(myClass);
final EValidator validatorForEObject = fixture.getEValidatorForEObject(my);
final BasicDiagnostic diagnostic = new BasicDiagnostic();
validatorForEObject.validate(myClass, my, diagnostic, null);
assertSame(Diagnostic.ERROR, diagnostic.getSeverity());
assertSame(1, diagnostic.getChildren().size());
assertSame(EObjectValidator.DIAGNOSTIC_SOURCE, diagnostic.getChildren().get(0).getSource());
assertSame(nameAttribute, diagnostic.getChildren().get(0).getData().get(1));
}
}