package org.cloudsmith.geppetto.pp.dsl.tests; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map.Entry; import org.eclipse.emf.ecore.resource.Resource.Diagnostic; import org.eclipse.xtext.diagnostics.AbstractDiagnostic; import com.google.common.base.Joiner; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; /** * Provides convenient predicates and assertions for testing Resource.Diganostic. * Use one instance of this class for {@link Resource#getErrors()}, and another for {@link Resource#getWarnings()}. * */ public class AssertableResourceDiagnostics { public interface DiagnosticPredicate extends Predicate<Diagnostic> { } protected static class Pred implements DiagnosticPredicate { protected String issueCode; protected String msg; public Pred(String issueCode, String msg) { super(); this.issueCode = issueCode; this.msg = msg; } public boolean apply(Diagnostic d) { if(msg != null && d.getMessage() != null && !d.getMessage().contains(msg)) return false; if(!(d instanceof AbstractDiagnostic)) return false; if(issueCode != null && !((AbstractDiagnostic) d).getCode().equals(issueCode)) return false; return true; } @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) + ")"; } } public static Pred diagnostic(String issueCode) { return new Pred(issueCode, null); } public static Pred diagnostic(String issueCode, String messageFragment) { return new Pred(issueCode, messageFragment); } protected List<Diagnostic> diag; public AssertableResourceDiagnostics(List<Diagnostic> diagnostics) { this.diag = diagnostics; } public void assertAll(DiagnosticPredicate... predicates) { HashMap<DiagnosticPredicate, Boolean> consumed = new HashMap<DiagnosticPredicate, Boolean>(); for(DiagnosticPredicate p : predicates) consumed.put(p, Boolean.FALSE); for(Diagnostic d : getAllDiagnostics()) { boolean found = false; for(Entry<DiagnosticPredicate, Boolean> e : consumed.entrySet()) if(!e.getValue() && e.getKey().apply(d)) { consumed.put(e.getKey(), Boolean.TRUE); found = true; break; } if(!found) { if(predicates.length == 1) fail("Predicate " + predicates[0] + " does not match " + d); else fail("No predicate in " + Arrays.toString(predicates) + " matches " + d); } } ArrayList<DiagnosticPredicate> unconsumed = new ArrayList<DiagnosticPredicate>(); for(Entry<DiagnosticPredicate, Boolean> e : consumed.entrySet()) if(!e.getValue()) unconsumed.add(e.getKey()); if(unconsumed.size() != 0) fail("There are diagnostics missing for theses predicates: " + unconsumed); } public AssertableResourceDiagnostics assertAny(DiagnosticPredicate... predicates) { for(DiagnosticPredicate predicate : predicates) if(Iterables.any(getAllDiagnostics(), predicate)) return this; fail("predicate not found"); return this; } public void assertDiagnostic(String issueCode) { assertAll(diagnostic(issueCode, null)); } public void assertDiagnostic(String issueCode, String messageFragment) { assertAll(diagnostic(issueCode, messageFragment)); } public void assertDiagnosticMsg(String messageFragment) { assertAll(diagnostic(null, messageFragment)); } public AssertableResourceDiagnostics assertDiagnosticsCount(int size) { int count = Iterables.size(getAllDiagnostics()); if(count == size) return this; fail("There are " + count + " diagnostics, but " + size + " are expected."); return this; } public void assertOK() { if(diag.size() != 0) fail("There are expected to be no diagnostics."); } public void fail(String message) { throw new AssertionError(message); } public Iterable<Diagnostic> getAllDiagnostics() { return new Iterable<Diagnostic>() { @Override public Iterator<Diagnostic> iterator() { return diag.iterator(); } }; } protected void printDiagnostic(StringBuffer out, String prefix, Diagnostic d) { // very simplistic... out.append(prefix); out.append(d); out.append("\n"); } @Override public String toString() { StringBuffer b = new StringBuffer(); for(Diagnostic d : diag) printDiagnostic(b, "", d); return b.toString(); } }