Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 27fda0c850259866c255c038d7fdda3e3a40b47d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*****************************************************************************
 * Copyright (c) 2014 CEA LIST and others.
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *   CEA LIST - Initial API and implementation
 *   
 *****************************************************************************/

package org.eclipse.papyrus.junit.utils.rules;

import static org.junit.Assert.fail;

import java.util.concurrent.Callable;

import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;


/**
 * Utilities for working with JUnit {@linkplain TestRule rules}.
 */
public class RuleUtil {

	private RuleUtil() {
		super();
	}

	/**
	 * Ad hoc invocation of an operation wrapped in the start/finish behaviour of a JUnit rule.
	 * 
	 * @param run
	 *        the operation to run
	 * @param rule
	 *        the rule to wrap it in
	 * 
	 * @throws Exception
	 *         on any exception thrown by the runnable or the rule
	 */
	public static void runWith(Runnable run, TestRule rule) throws Exception {
		callWith(call(run), rule);
	}

	/**
	 * Safe ad hoc invocation of an operation wrapped in the start/finish behaviour of a JUnit rule.
	 * Fails JUnitishly on any exception in the callable or the rule.
	 * 
	 * @param run
	 *        the operation to run
	 * @param rule
	 *        the rule to wrap it in
	 */
	public static void safeRunWith(Runnable run, TestRule rule) throws Exception {
		safeCallWith(call(run), rule);
	}

	static Callable<?> call(final Runnable run) {
		return new Callable<Void>() {

			public Void call() throws Exception {
				run.run();
				return null;
			}
		};
	}

	/**
	 * Ad hoc invocation of a callable wrapped in the start/finish behaviour of a JUnit rule.
	 * 
	 * @param callable
	 *        the callable to execute
	 * @param rule
	 *        the rule to wrap it in
	 * 
	 * @throws Exception
	 *         on any exception thrown by the callable or the rule
	 */
	public static <V> V callWith(Callable<V> callable, TestRule rule) throws Exception {
		class CallableStatement extends Statement {

			final Callable<V> callable;

			V result;

			CallableStatement(Callable<V> callable) {
				this.callable = callable;
			}

			@Override
			public void evaluate() throws Throwable {
				result = callable.call();
			}
		}

		try {
			CallableStatement statement = new CallableStatement(callable);
			rule.apply(statement, Description.EMPTY).evaluate();
			return statement.result;
		} catch (Throwable t) {
			if(t instanceof Exception) {
				throw (Exception)t;
			} else {
				throw (Error)t;
			}
		}
	}

	/**
	 * Safe ad hoc invocation of a callable wrapped in the start/finish behaviour of a JUnit rule.
	 * Fails JUnitishly on any exception in the callable or the rule.
	 * 
	 * @param callable
	 *        the callable to execute
	 * @param rule
	 *        the rule to wrap it in
	 */
	public static <V> V safeCallWith(Callable<V> callable, TestRule rule) {
		try {
			return callWith(callable, rule);
		} catch (Exception e) {
			e.printStackTrace();
			fail("Failed to invoke callable with rule: " + e.getLocalizedMessage());
			return null; // Unreachable
		}
	}

}

Back to the top