/** * Copyright (c) 2011 Cloudsmith Inc. and other contributors, as listed below. * 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: * Cloudsmith * */ package org.cloudsmith.geppetto.pp.dsl.tests.utils; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map.Entry; import junit.framework.ComparisonFailure; import org.eclipse.emf.ecore.resource.Resource.Diagnostic; import org.eclipse.xtext.resource.XtextResource; import org.eclipse.xtext.validation.AbstractValidationDiagnostic; import com.google.common.base.Joiner; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; /** * Helper class making it easier to assert content of a Resource.Diagnostic * */ public class DiagnosticsAsserter { public interface DiagnosticPredicate extends Predicate<Diagnostic> { public DiagnosticPredicate greedy(); public boolean isGreedy(); public boolean isRequired(); public DiagnosticPredicate optional(); } protected static class IssuePredicate implements DiagnosticPredicate { protected String issueCode; protected boolean optional; protected boolean greedy; protected String msg; public IssuePredicate(String issueCode) { this(issueCode, null); } public IssuePredicate(String issueCode, String msg) { this.issueCode = issueCode; this.msg = msg; this.optional = false; this.greedy = false; } public boolean apply(Diagnostic d) { if(msg != null && d.getMessage() != null && !d.getMessage().contains(msg)) return false; AbstractValidationDiagnostic issue = null; if(d instanceof AbstractValidationDiagnostic) issue = (AbstractValidationDiagnostic) d; if(issueCode != null && (issue == null || !issue.getIssueCode().equals(issueCode))) return false; return true; } public IssuePredicate greedy() { this.greedy = true; return this; } public boolean isGreedy() { return greedy; } public boolean isRequired() { return !optional; } public IssuePredicate optional() { this.optional = true; return this; } @Override public String toString() { List<String> r = new ArrayList<String>(); if(issueCode != null) r.add("issueCode=" + issueCode); if(msg != null) r.add("msgFragment='" + msg + "'"); return "(" + Joiner.on(" ").join(r) + ")"; } } private XtextResource resource; public DiagnosticsAsserter(XtextResource resource) { this.resource = resource; } public void assertAll(DiagnosticPredicate... predicates) { assertAll(getAllDiagnostics(), predicates); } public void assertAll(Iterable<Diagnostic> asserted, DiagnosticPredicate predicates[]) { HashMap<DiagnosticPredicate, Boolean> consumed = new HashMap<DiagnosticPredicate, Boolean>(); for(DiagnosticPredicate p : predicates) consumed.put(p, Boolean.FALSE); for(Diagnostic d : asserted) { boolean found = false; for(Entry<DiagnosticPredicate, Boolean> e : consumed.entrySet()) if((!e.getValue() || e.getKey().isGreedy()) && e.getKey().apply(d)) { consumed.put(e.getKey(), Boolean.TRUE); found = true; break; } if(!found) { if(predicates.length == 1) throw new ComparisonFailure( "Predicate does not match", predicates[0].toString(), diagnosticsToString(d)); throw new ComparisonFailure( "No predicate in expected matches", Arrays.toString(predicates), diagnosticsToString(d)); } } ArrayList<DiagnosticPredicate> unconsumed = new ArrayList<DiagnosticPredicate>(); for(Entry<DiagnosticPredicate, Boolean> e : consumed.entrySet()) if(!e.getValue() && e.getKey().isRequired()) unconsumed.add(e.getKey()); if(unconsumed.size() != 0) throw new ComparisonFailure( "Missing diagnostics for required predicates", Arrays.toString(unconsumed.toArray()), diagnosticsToString(asserted)); } public void assertAny(Iterable<Diagnostic> asserted, DiagnosticPredicate... predicates) { for(DiagnosticPredicate predicate : predicates) if(Iterables.any(asserted, predicate)) return; throw new ComparisonFailure( "No predicate (any expected) matches diagnostics", Arrays.toString(predicates), diagnosticsToString(asserted)); } /** * Warnings and/or errors must be present. */ public void assertErrors() { List<Diagnostic> diagnostics = resource.getErrors(); if(diagnostics.size() < 1) throw new ComparisonFailure("Error Diagnostics expected", "> 0 Diagnostics", ""); } public void assertErrors(DiagnosticPredicate... predicates) { assertAll(resource.getErrors(), predicates); } /** * No errors or warnings accepted. * * @param message * @param diag */ public void assertOk() { Iterable<Diagnostic> all = getAllDiagnostics(); if(Iterables.size(all) > 0) throw new ComparisonFailure("No diagnostics expected", "No diagnostics", diagnosticsToString(all)); } public void assertWarnings() { List<Diagnostic> diagnostics = resource.getWarnings(); if(diagnostics.size() < 1) throw new ComparisonFailure("Warning Diagnostics expected", "> 0 Diagnostics", ""); } public void assertWarnings(DiagnosticPredicate... predicates) { assertAll(resource.getWarnings(), predicates); } public String diagnosticsToString(Diagnostic d) { StringBuilder builder = new StringBuilder(); builder.append(d.toString()); builder.append("\n"); return builder.toString(); } public String diagnosticsToString(Iterable<Diagnostic> diag) { StringBuilder builder = new StringBuilder(); for(Diagnostic d : diag) { AbstractValidationDiagnostic issue = null; if(d instanceof AbstractValidationDiagnostic) issue = (AbstractValidationDiagnostic) d; if(issue != null) { // ResourceExceptions, do not have severity // if(d.getSeverity() == Diagnostic.ERROR) // builder.append("ERROR "); // else // builder.append("WARNING "); AbstractValidationDiagnostic detail = issue; builder.append("issueCode="); builder.append(detail.getIssueCode()); builder.append(" "); builder.append("msg='"); builder.append(d.getMessage()); builder.append("'"); } else builder.append(d.toString()); builder.append("\n"); } return builder.toString(); } public Iterable<Diagnostic> getAllDiagnostics() { return Iterables.concat(resource.getWarnings(), resource.getErrors()); } public DiagnosticPredicate issue(String issueCode) { return new IssuePredicate(issueCode, null); } public DiagnosticPredicate issue(String issueCode, String messageFragment) { return new IssuePredicate(issueCode, messageFragment); } public DiagnosticPredicate messageFragment(String messageFragment) { return new IssuePredicate(null, messageFragment); } }