13 | * The following are equivalent: 14 | *
15 | * public class MyTests {
16 | * enum Color { RED, BLUE }
17 | *
18 | * private final Color color;
19 | *
20 | * public MyTests(Color color) {
21 | * this.color = color;
22 | * }
23 | *
24 | * …
25 | * }
26 | *
27 | *
28 | * public class MyTests {
29 | * enum Color { RED, BLUE }
30 | *
31 | * {@literal @}Burst private Color color;
32 | *
33 | * …
34 | * }
35 | *
36 | */
37 | @Retention(RetentionPolicy.RUNTIME)
38 | @Target(ElementType.FIELD)
39 | public @interface Burst {
40 | }
41 |
--------------------------------------------------------------------------------
/.buildscript/deploy_snapshot.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Deploy a jar, source jar, and javadoc jar to Sonatype's snapshot repo.
4 | #
5 | # Adapted from https://coderwall.com/p/9b_lfq and
6 | # http://benlimmer.com/2013/12/26/automatically-publish-javadoc-to-gh-pages-with-travis-ci/
7 |
8 | SLUG="square/burst"
9 | JDK="openjdk8"
10 | BRANCH="master"
11 |
12 | set -e
13 |
14 | if [ "$TRAVIS_REPO_SLUG" != "$SLUG" ]; then
15 | echo "Skipping snapshot deployment: wrong repository. Expected '$SLUG' but was '$TRAVIS_REPO_SLUG'."
16 | elif [ "$TRAVIS_JDK_VERSION" != "$JDK" ]; then
17 | echo "Skipping snapshot deployment: wrong JDK. Expected '$JDK' but was '$TRAVIS_JDK_VERSION'."
18 | elif [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
19 | echo "Skipping snapshot deployment: was pull request."
20 | elif [ "$TRAVIS_BRANCH" != "$BRANCH" ]; then
21 | echo "Skipping snapshot deployment: wrong branch. Expected '$BRANCH' but was '$TRAVIS_BRANCH'."
22 | else
23 | echo "Deploying snapshot..."
24 | mvn clean source:jar javadoc:jar deploy --settings=".buildscript/settings.xml" -Dmaven.test.skip=true
25 | echo "Snapshot deployed!"
26 | fi
27 |
--------------------------------------------------------------------------------
/burst-junit4/src/test/java/com/squareup/burst/ParentRunnerSpyTest.java:
--------------------------------------------------------------------------------
1 | package com.squareup.burst;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import org.junit.Test;
6 | import org.junit.runner.Description;
7 | import org.junit.runner.notification.RunNotifier;
8 | import org.junit.runners.ParentRunner;
9 |
10 | import static org.junit.Assert.assertEquals;
11 |
12 | public class ParentRunnerSpyTest {
13 |
14 | @Test
15 | public void testGetFilteredChildren() throws Exception {
16 | List12 | * The following snippet: 13 | *
14 | * package com.example.yourpackage
15 | *
16 | * public class MyTests {
17 | * enum BooleanCondition { TRUE, FALSE }
18 | *
19 | * {@literal @}Name("IsEnabled") private BooleanCondition isEnabled;
20 | * {@literal @}Name("IsFlagged") private BooleanCondition isFlagged;
21 | *
22 | * …
23 | *
24 | * {@literal @}Test
25 | * public void testConditions() {
26 | * …
27 | * }
28 | * }
29 | *
30 | * Would produce output like this in the runner:
31 | * 32 | * testCondition[](com.example.yourpackage.MyTest[IsEnabled=TRUE, IsFlagged=TRUE]) 33 | * testCondition[](com.example.yourpackage.MyTest[IsEnabled=TRUE, IsFlagged=FALSE]) 34 | * testCondition[](com.example.yourpackage.MyTest[IsEnabled=FALSE, IsFlagged=TRUE]) 35 | * testCondition[](com.example.yourpackage.MyTest[IsEnabled=FALSE, IsFlagged=FALSE]) 36 | *37 | */ 38 | @Retention(RetentionPolicy.RUNTIME) 39 | @Target({ ElementType.FIELD, ElementType.PARAMETER }) 40 | public @interface Name { 41 | 42 | /** 43 | * @return The String value that Burst should use for the name in test output. 44 | */ 45 | String value(); 46 | } 47 | -------------------------------------------------------------------------------- /burst-junit4/src/test/java/com/squareup/burst/RuleUsingAnnotationsTest.java: -------------------------------------------------------------------------------- 1 | package com.squareup.burst; 2 | 3 | import java.lang.annotation.Annotation; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.Target; 6 | import java.util.Collection; 7 | import org.junit.Rule; 8 | import org.junit.Test; 9 | import org.junit.rules.TestWatcher; 10 | import org.junit.runner.Description; 11 | import org.junit.runner.RunWith; 12 | 13 | import static java.lang.annotation.ElementType.METHOD; 14 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 15 | import static org.junit.Assert.assertEquals; 16 | import static org.junit.Assert.assertTrue; 17 | 18 | @RunWith(BurstJUnit4.class) 19 | public class RuleUsingAnnotationsTest { 20 | 21 | @Target(METHOD) 22 | @Retention(RUNTIME) @interface CustomAnnotation { 23 | 24 | } 25 | 26 | static class RuleWithAnnotation extends TestWatcher { 27 | 28 | Collection
33 | * This would be problematic for us since we generate non-standard test descriptions which include
34 | * parameter information. This implementation lets each {@link BurstRunner} child filter itself
35 | * via {@link BurstRunner#filter(Filter)}.
36 | */
37 | @Override public void filter(Filter filter) throws NoTestsRemainException {
38 | List
84 | * This would be problematic for us since we generate non-standard test descriptions which include
85 | * parameter information. This implementation generates "plain" descriptions without parameter
86 | * information and passes those to the filter.
87 | */
88 | @Override public void filter(Filter filter) throws NoTestsRemainException {
89 | List
59 | * Constructor arguments should be first in the array, followed by field arguments.
60 | */
61 | public Object newInstance(Object[] args)
62 | throws IllegalAccessException, InvocationTargetException, InstantiationException {
63 | if (args.length != getVariationTypes().length) {
64 | throw new IllegalArgumentException(String.format(
65 | "Constructor takes %d values, only %d passed", getVariationTypes().length, args.length));
66 | }
67 |
68 | // Partition arg list
69 | final Object[] ctorArgs = extractConstructorArgs(args);
70 | final Object[] fieldArgs = extractFieldArgs(args);
71 |
72 | final Object instance = newInstanceWithoutFields(ctorArgs);
73 | initializeFieldsOnInstance(instance, fieldArgs);
74 | return instance;
75 | }
76 |
77 | /**
78 | * @return array containing the elements of
44 | * For example, a method named "snackBreak" being invoked with constructor arguments
45 | * {@code Drink.SODA} and {@code Snack.ALMONDS} and method arguments {@code BreakTime.AFTERNOON}
46 | * would produce "snackBreak_SODA_ALMONDS_AFTERNOON".
47 | *
48 | * @throws ClassCastException If any element of {@code constructorArgs} or {@code methodArgs} is
49 | * not an enum value.
50 | */
51 | public static String friendlyName(Enum>[] arguments) {
52 | return friendlyName(arguments, new Annotation[0][0]);
53 | }
54 |
55 | /**
56 | * Creates an "exploded" test name which includes information about the {@code constructorArgs}
57 | * and {@code methodArgs}. This will append both the enum class and enum value name for every
58 | * argument in order.
59 | *
60 | * For example, a method named "snackBreak" being invoked with constructor arguments
61 | * {@code Drink.SODA} and {@code Snack.ALMONDS} and method arguments {@code BreakTime.AFTERNOON}
62 | * would produce "snackBreak_SODA_ALMONDS_AFTERNOON".
63 | *
64 | * If any of the arguments have an {@literal @}Name annotation, the enum class name will be
65 | * replaced with the value provided in the annotation.
66 | *
67 | * @throws ClassCastException If any element of {@code constructorArgs} or {@code methodArgs} is
68 | * not an enum value.
69 | */
70 | public static String friendlyName(Enum>[] arguments, Annotation[][] argumentAnnotations) {
71 | checkNotNull(arguments, "arguments");
72 | if (arguments.length == 0) {
73 | return "";
74 | }
75 |
76 | StringBuilder builder = new StringBuilder();
77 | for (int i = 0; i < arguments.length; i++) {
78 | Object argument = arguments[i];
79 | if (builder.length() > 0) {
80 | builder.append(", ");
81 | }
82 |
83 | Enum> value = (Enum>) argument;
84 | // Appends the enum name and value name. (e.g., Card.VISA)
85 | if (argumentAnnotations.length > i) {
86 | for (Annotation annotation : argumentAnnotations[i]) {
87 | if (annotation instanceof Name) {
88 | String name = ((Name) annotation).value();
89 | builder.append(name).append('=');
90 | break;
91 | }
92 | }
93 | }
94 | builder.append(value);
95 | }
96 | return builder.toString();
97 | }
98 |
99 | private static Enum>[][] explodeParameters(Class>[] parameterTypes, String name) {
100 | int parameterCount = parameterTypes.length;
101 | if (parameterCount == 0) {
102 | return NONE;
103 | }
104 |
105 | int count = 1; // Total variation count.
106 | Enum>[][] valuesList = new Enum>[parameterCount][];
107 |
108 | for (int i = 0; i < parameterCount; i++) {
109 | Class> parameterType = parameterTypes[i];
110 | if (!parameterType.isEnum()) {
111 | throw new IllegalStateException(name
112 | + " parameter #"
113 | + (i + 1)
114 | + " type is not an enum. ("
115 | + parameterType.getName()
116 | + ')');
117 | }
118 | //noinspection unchecked
119 | Class extends Enum>> enumType = (Class extends Enum>>) parameterType;
120 |
121 | Enum>[] values = enumType.getEnumConstants();
122 | valuesList[i] = values;
123 | count *= values.length;
124 | }
125 | return explode(count, valuesList);
126 | }
127 |
128 | private static Enum>[][] explode(int count, Enum>[][] valuesList) {
129 | // The number of times to replay iterating over individual enum values.
130 | int replays = 1;
131 | // The number of times to repeat an enum value.
132 | int adjacent = count;
133 |
134 | Enum>[][] arguments = new Enum>[count][valuesList.length];
135 | for (int valuesIndex = 0; valuesIndex < valuesList.length; valuesIndex++) {
136 | Enum>[] values = valuesList[valuesIndex];
137 |
138 | // Gap between replays is the previous number of adjacent values.
139 | int replayGap = adjacent;
140 | // The number of adjacent is divided among the number of current values.
141 | adjacent /= values.length;
142 |
143 | for (int replay = 0; replay < replays; replay++) {
144 | int replayOffset = replay * replayGap;
145 | for (int valueIndex = 0; valueIndex < values.length; valueIndex++) {
146 | int valueOffset = valueIndex * adjacent;
147 | for (int i = 0; i < adjacent; i++) {
148 | arguments[replayOffset + valueOffset + i][valuesIndex] = values[valueIndex];
149 | }
150 | }
151 | }
152 |
153 | // Increase the iteration replays by the number of values in the current enum.
154 | replays *= values.length;
155 | }
156 |
157 | return arguments;
158 | }
159 |
160 | private Burst() {
161 | throw new AssertionError("No instances.");
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/burst/src/test/java/com/squareup/burst/BurstableConstructorTest.java:
--------------------------------------------------------------------------------
1 | package com.squareup.burst;
2 |
3 | import com.squareup.burst.annotation.Burst;
4 | import org.junit.Rule;
5 | import org.junit.Test;
6 | import org.junit.rules.ExpectedException;
7 |
8 | import static org.assertj.core.api.Assertions.assertThat;
9 |
10 | public class BurstableConstructorTest {
11 | enum First { }
12 | enum Second { }
13 |
14 | @Rule public final ExpectedException thrown = ExpectedException.none();
15 |
16 | public static class None {
17 | }
18 | @Test public void noConstructor() {
19 | TestConstructor ctor = BurstableConstructor.findSingle(None.class);
20 | assertThat(ctor.getVariationTypes()).isEmpty();
21 | }
22 |
23 | public static class Default {
24 | public Default() {}
25 | }
26 | @Test public void defaultConstructor() {
27 | TestConstructor ctor = BurstableConstructor.findSingle(Default.class);
28 | assertThat(ctor.getVariationTypes()).isEmpty();
29 | }
30 |
31 | public static class One {
32 | public One(First first) {}
33 | }
34 | @Test public void singleParameterizedConstructor() {
35 | TestConstructor ctor = BurstableConstructor.findSingle(One.class);
36 | assertThat(ctor.getVariationTypes()).containsExactly(First.class);
37 | }
38 |
39 | public static class DefaultAndOne {
40 | public DefaultAndOne() {}
41 | public DefaultAndOne(First first) {}
42 | }
43 | @Test public void defaultAndParameterizedConstructor() {
44 | thrown.expect(IllegalStateException.class);
45 | thrown.expectMessage("too many parameterized constructors");
46 |
47 | BurstableConstructor.findSingle(DefaultAndOne.class);
48 | }
49 |
50 | public static class NonPublicConstructor {
51 | NonPublicConstructor() {}
52 | }
53 | @Test public void nonPublic() {
54 | thrown.expect(IllegalStateException.class);
55 | thrown.expectMessage("requires at least 1 public constructor");
56 |
57 | BurstableConstructor.findSingle(NonPublicConstructor.class);
58 | }
59 |
60 | public static class TooMany {
61 | public TooMany(First first) {}
62 | public TooMany(Second second) {}
63 | }
64 | @Test public void tooMany() {
65 | thrown.expect(IllegalStateException.class);
66 | thrown.expectMessage(
67 | "has too many parameterized constructors. Should only be 1 (with enum variations).");
68 |
69 | BurstableConstructor.findSingle(TooMany.class);
70 | }
71 |
72 | public static class NonEnumInConstructor {
73 | public NonEnumInConstructor(Object first) {}
74 | }
75 | @Test public void nonEnumInConstructor() {
76 | TestConstructor ctor = BurstableConstructor.findSingle(NonEnumInConstructor.class);
77 | assertThat(ctor.getVariationTypes()).containsExactly(Object.class);
78 | }
79 |
80 | public static class NotAnEnumInConstructor {
81 | public NotAnEnumInConstructor(Object first) {}
82 | }
83 | @Test public void notAnEnumInConstructor() {
84 | TestConstructor ctor = BurstableConstructor.findSingle(NotAnEnumInConstructor.class);
85 | assertThat(ctor.getVariationTypes()).containsExactly(Object.class);
86 | }
87 |
88 | public static class DefaultWithField {
89 | @Burst First first;
90 | }
91 | @Test public void defaultConstructorWithField() {
92 | TestConstructor ctor = BurstableConstructor.findSingle(DefaultWithField.class);
93 | assertThat(ctor.getVariationTypes()).containsExactly(First.class);
94 | }
95 |
96 | public static class NoneWithField {
97 | @Burst First first;
98 | public NoneWithField() {}
99 | }
100 | @Test public void singleEmptyConstructorWithField() {
101 | TestConstructor ctor = BurstableConstructor.findSingle(NoneWithField.class);
102 | assertThat(ctor.getVariationTypes()).containsExactly(First.class);
103 | }
104 |
105 | public static class MultipleFields {
106 | @Burst First first;
107 | @Burst Second second;
108 | }
109 | @Test public void emptyConstructorMultipleFields() {
110 | TestConstructor ctor = BurstableConstructor.findSingle(MultipleFields.class);
111 | assertThat(ctor.getVariationTypes()).containsOnly(First.class, Second.class);
112 | }
113 |
114 | public static class OneWithField {
115 | @Burst Second second;
116 | public OneWithField(First first) {}
117 | }
118 | @Test public void singleParameterizedConstructorWithField() {
119 | thrown.expectMessage(
120 | "has a parameterized constructor, so cannot also be parameterized on fields");
121 |
122 | BurstableConstructor.findSingle(OneWithField.class);
123 | }
124 |
125 | public static class PrivateField {
126 | @Burst private First first;
127 | }
128 | @Test public void privateAnnotatedField() {
129 | TestConstructor ctor = BurstableConstructor.findSingle(PrivateField.class);
130 | assertThat(ctor.getVariationTypes()).containsExactly(First.class);
131 | }
132 |
133 | public static class InheritedField extends PrivateField {
134 | @Burst Second second;
135 | }
136 | @Test public void inheritedField() {
137 | TestConstructor ctor = BurstableConstructor.findSingle(InheritedField.class);
138 | assertThat(ctor.getVariationTypes()).containsOnly(First.class, Second.class);
139 | }
140 |
141 | public static class StaticField {
142 | @Burst static First first;
143 | }
144 | @Test public void StaticField() {
145 | thrown.expect(IllegalStateException.class);
146 | thrown.expectMessage("Burstable field must not be static");
147 |
148 | BurstableConstructor.findSingle(StaticField.class);
149 | }
150 |
151 | public static class FinalField {
152 | @Burst final First first = null;
153 | }
154 | @Test public void finalField() {
155 | thrown.expect(IllegalStateException.class);
156 | thrown.expectMessage("Burstable field must not be final");
157 |
158 | BurstableConstructor.findSingle(FinalField.class);
159 | }
160 |
161 | public static class NotAnEnumField {
162 | @Burst Object first;
163 | }
164 | @Test public void notAnEnumField() {
165 | TestConstructor ctor = BurstableConstructor.findSingle(NotAnEnumField.class);
166 | assertThat(ctor.getVariationTypes()).containsExactly(Object.class);
167 | }
168 |
169 | public static class UnannotatedField {
170 | First first;
171 | @Burst Second second;
172 | }
173 | @Test public void unannotatedField() {
174 | TestConstructor ctor = BurstableConstructor.findSingle(UnannotatedField.class);
175 | assertThat(ctor.getVariationTypes()).containsExactly(Second.class);
176 | }
177 | }
178 |
--------------------------------------------------------------------------------
/burst/src/test/java/com/squareup/burst/BurstTest.java:
--------------------------------------------------------------------------------
1 | package com.squareup.burst;
2 |
3 | import org.junit.Rule;
4 | import org.junit.Test;
5 | import org.junit.rules.ExpectedException;
6 | import java.lang.annotation.Annotation;
7 | import java.lang.reflect.Method;
8 |
9 | import static org.assertj.core.api.Assertions.assertThat;
10 |
11 | /** Reflection on constructors, methods, and their parameters. */
12 | @SuppressWarnings("UnusedDeclaration")
13 | public class BurstTest {
14 | enum First { APPLE, BEARD, COUCH }
15 | enum Second { DINGO, EAGLE }
16 | enum Third { FRANK, GREAT, HEAVY, ITALY }
17 |
18 | public static class One {
19 | public One(First first) {}
20 | }
21 | public static class Three {
22 | public Three(First first, Second second, Third third) {}
23 | }
24 |
25 | public static class Bad {
26 | public Bad(Object o) {}
27 | }
28 |
29 | @Rule public final ExpectedException thrown = ExpectedException.none();
30 |
31 | @Test public void nonEnumConstructorParameter() {
32 | TestConstructor constructor = new TestConstructor(Bad.class.getConstructors()[0]);
33 |
34 | thrown.expect(IllegalStateException.class);
35 | thrown.expectMessage(Bad.class.getName()
36 | + " constructor parameter #1 type is not an enum. (java.lang.Object)");
37 |
38 | Burst.explodeArguments(constructor);
39 | }
40 |
41 | @Test public void singleConstructorParameter() {
42 | TestConstructor constructor = new TestConstructor(One.class.getConstructors()[0]);
43 | Object[][] objects = Burst.explodeArguments(constructor);
44 | assertThat(objects).containsExactly(
45 | new Object[] { First.APPLE },
46 | new Object[] { First.BEARD },
47 | new Object[] { First.COUCH }
48 | );
49 | }
50 |
51 | @Test public void multipleConstructorParameters() {
52 | TestConstructor constructor = new TestConstructor(Three.class.getConstructors()[0]);
53 | Object[][] objects = Burst.explodeArguments(constructor);
54 | assertThat(objects).containsExactly(
55 | new Object[] { First.APPLE, Second.DINGO, Third.FRANK },
56 | new Object[] { First.APPLE, Second.DINGO, Third.GREAT },
57 | new Object[] { First.APPLE, Second.DINGO, Third.HEAVY },
58 | new Object[] { First.APPLE, Second.DINGO, Third.ITALY },
59 | new Object[] { First.APPLE, Second.EAGLE, Third.FRANK },
60 | new Object[] { First.APPLE, Second.EAGLE, Third.GREAT },
61 | new Object[] { First.APPLE, Second.EAGLE, Third.HEAVY },
62 | new Object[] { First.APPLE, Second.EAGLE, Third.ITALY },
63 | new Object[] { First.BEARD, Second.DINGO, Third.FRANK },
64 | new Object[] { First.BEARD, Second.DINGO, Third.GREAT },
65 | new Object[] { First.BEARD, Second.DINGO, Third.HEAVY },
66 | new Object[] { First.BEARD, Second.DINGO, Third.ITALY },
67 | new Object[] { First.BEARD, Second.EAGLE, Third.FRANK },
68 | new Object[] { First.BEARD, Second.EAGLE, Third.GREAT },
69 | new Object[] { First.BEARD, Second.EAGLE, Third.HEAVY },
70 | new Object[] { First.BEARD, Second.EAGLE, Third.ITALY },
71 | new Object[] { First.COUCH, Second.DINGO, Third.FRANK },
72 | new Object[] { First.COUCH, Second.DINGO, Third.GREAT },
73 | new Object[] { First.COUCH, Second.DINGO, Third.HEAVY },
74 | new Object[] { First.COUCH, Second.DINGO, Third.ITALY },
75 | new Object[] { First.COUCH, Second.EAGLE, Third.FRANK },
76 | new Object[] { First.COUCH, Second.EAGLE, Third.GREAT },
77 | new Object[] { First.COUCH, Second.EAGLE, Third.HEAVY },
78 | new Object[] { First.COUCH, Second.EAGLE, Third.ITALY }
79 | );
80 | }
81 |
82 | @Test public void noMethodParameters() throws NoSuchMethodException {
83 | class Example {
84 | public void example() {}
85 | }
86 | Method method = Example.class.getMethod("example");
87 |
88 | Object[][] objects = Burst.explodeArguments(method);
89 | assertThat(objects).containsExactly(new Object[0]);
90 | }
91 |
92 | @Test public void nonEnumMethodParameter() throws NoSuchMethodException {
93 | class Example {
94 | public void example(Object o) {}
95 | }
96 | Method method = Example.class.getMethod("example", Object.class);
97 |
98 | thrown.expect(IllegalStateException.class);
99 | thrown.expectMessage(Example.class.getName()
100 | + ".example method parameter #1 type is not an enum. (java.lang.Object)");
101 |
102 | Burst.explodeArguments(method);
103 | }
104 |
105 | @Test public void singleMethodParameters() throws NoSuchMethodException {
106 | class Example {
107 | public void example(First first) {}
108 | }
109 | Method method = Example.class.getMethod("example", First.class);
110 |
111 | Object[][] objects = Burst.explodeArguments(method);
112 | assertThat(objects).containsExactly(
113 | new Object[] { First.APPLE },
114 | new Object[] { First.BEARD },
115 | new Object[] { First.COUCH }
116 | );
117 | }
118 |
119 | @Test public void multipleMethodParameters() throws NoSuchMethodException {
120 | class Example {
121 | public void example(First first, Second second, Third third) {}
122 | }
123 | Method method = Example.class.getMethod("example", First.class, Second.class, Third.class);
124 |
125 | Object[][] objects = Burst.explodeArguments(method);
126 | assertThat(objects).containsExactly(
127 | new Object[] { First.APPLE, Second.DINGO, Third.FRANK },
128 | new Object[] { First.APPLE, Second.DINGO, Third.GREAT },
129 | new Object[] { First.APPLE, Second.DINGO, Third.HEAVY },
130 | new Object[] { First.APPLE, Second.DINGO, Third.ITALY },
131 | new Object[] { First.APPLE, Second.EAGLE, Third.FRANK },
132 | new Object[] { First.APPLE, Second.EAGLE, Third.GREAT },
133 | new Object[] { First.APPLE, Second.EAGLE, Third.HEAVY },
134 | new Object[] { First.APPLE, Second.EAGLE, Third.ITALY },
135 | new Object[] { First.BEARD, Second.DINGO, Third.FRANK },
136 | new Object[] { First.BEARD, Second.DINGO, Third.GREAT },
137 | new Object[] { First.BEARD, Second.DINGO, Third.HEAVY },
138 | new Object[] { First.BEARD, Second.DINGO, Third.ITALY },
139 | new Object[] { First.BEARD, Second.EAGLE, Third.FRANK },
140 | new Object[] { First.BEARD, Second.EAGLE, Third.GREAT },
141 | new Object[] { First.BEARD, Second.EAGLE, Third.HEAVY },
142 | new Object[] { First.BEARD, Second.EAGLE, Third.ITALY },
143 | new Object[] { First.COUCH, Second.DINGO, Third.FRANK },
144 | new Object[] { First.COUCH, Second.DINGO, Third.GREAT },
145 | new Object[] { First.COUCH, Second.DINGO, Third.HEAVY },
146 | new Object[] { First.COUCH, Second.DINGO, Third.ITALY },
147 | new Object[] { First.COUCH, Second.EAGLE, Third.FRANK },
148 | new Object[] { First.COUCH, Second.EAGLE, Third.GREAT },
149 | new Object[] { First.COUCH, Second.EAGLE, Third.HEAVY },
150 | new Object[] { First.COUCH, Second.EAGLE, Third.ITALY }
151 | );
152 | }
153 |
154 | @Test public void noArguments() {
155 | String actual = Burst.friendlyName(new Enum>[0]);
156 | assertThat(actual).isEqualTo("");
157 | }
158 |
159 | @Test public void singleArgument() {
160 | String actual = Burst.friendlyName(new Enum>[] { First.APPLE });
161 | assertThat(actual).isEqualTo("APPLE");
162 | }
163 |
164 | @Test public void multipleArguments() {
165 | String actual = Burst.friendlyName(new Enum>[] { First.APPLE, Second.EAGLE, Third.ITALY });
166 | assertThat(actual).isEqualTo("APPLE, EAGLE, ITALY");
167 | }
168 |
169 | @Test public void singleArgument_named() {
170 | String actual = Burst.friendlyName(new Enum>[] { First.APPLE }, new Annotation[][] {
171 | {TestUtil.createName("Fruit")}
172 | });
173 | assertThat(actual).isEqualTo("Fruit=APPLE");
174 | }
175 |
176 | @Test public void multipleArguments_named() {
177 | String actual = Burst.friendlyName(new Enum>[] { First.APPLE, Second.EAGLE, Third.ITALY }, new Annotation[][] {
178 | {TestUtil.createName("Fruit")},
179 | {TestUtil.createName("Bird")},
180 | {TestUtil.createName("Country")}
181 | });
182 | assertThat(actual).isEqualTo("Fruit=APPLE, Bird=EAGLE, Country=ITALY");
183 | }
184 |
185 | @Test public void multipleArguments_multipleAnnotations_named() {
186 | String actual = Burst.friendlyName(new Enum>[] { First.APPLE, Second.EAGLE, Third.ITALY }, new Annotation[][] {
187 | {TestUtil.createFake(), TestUtil.createName("Fruit")},
188 | {TestUtil.createFake(), TestUtil.createName("Bird")},
189 | {TestUtil.createName("Country"), TestUtil.createFake()}
190 | });
191 | assertThat(actual).isEqualTo("Fruit=APPLE, Bird=EAGLE, Country=ITALY");
192 | }
193 |
194 | }
195 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/burst-junit4/src/test/java/com/squareup/burst/BurstJUnit4Test.java:
--------------------------------------------------------------------------------
1 | package com.squareup.burst;
2 |
3 | import org.junit.Test;
4 | import org.junit.runners.model.InitializationError;
5 |
6 | import static org.assertj.core.api.Assertions.assertThat;
7 |
8 | public final class BurstJUnit4Test {
9 | private final JournalingListener listener = new JournalingListener();
10 |
11 | @Test public void constructorNone() throws InitializationError {
12 | BurstJUnit4 runner = new BurstJUnit4(ConstructorNoArgumentTest.class);
13 | runner.run(listener.notifier());
14 | assertThat(listener.journal()).containsExactly(
15 | "START testMethod(com.squareup.burst.ConstructorNoArgumentTest)",
16 | "FINISH testMethod(com.squareup.burst.ConstructorNoArgumentTest)");
17 | }
18 |
19 | @Test public void constructorSingle() throws InitializationError {
20 | BurstJUnit4 runner = new BurstJUnit4(ConstructorSingleArgumentTest.class);
21 | runner.run(listener.notifier());
22 | assertThat(listener.journal()).containsExactly(
23 | "START testMethod(com.squareup.burst.ConstructorSingleArgumentTest[PEPSI])",
24 | "FINISH testMethod(com.squareup.burst.ConstructorSingleArgumentTest[PEPSI])",
25 | "START testMethod(com.squareup.burst.ConstructorSingleArgumentTest[COKE])",
26 | "FINISH testMethod(com.squareup.burst.ConstructorSingleArgumentTest[COKE])",
27 | "START testMethod(com.squareup.burst.ConstructorSingleArgumentTest[RC_COLA])",
28 | "FINISH testMethod(com.squareup.burst.ConstructorSingleArgumentTest[RC_COLA])");
29 | }
30 |
31 | @Test public void constructorSingleNamed() throws InitializationError {
32 | BurstJUnit4 runner = new BurstJUnit4(ConstructorSingleNamedArgumentTest.class);
33 | runner.run(listener.notifier());
34 | assertThat(listener.journal()).containsExactly(
35 | "START testMethod(com.squareup.burst.ConstructorSingleNamedArgumentTest[Drink=PEPSI])",
36 | "FINISH testMethod(com.squareup.burst.ConstructorSingleNamedArgumentTest[Drink=PEPSI])",
37 | "START testMethod(com.squareup.burst.ConstructorSingleNamedArgumentTest[Drink=COKE])",
38 | "FINISH testMethod(com.squareup.burst.ConstructorSingleNamedArgumentTest[Drink=COKE])",
39 | "START testMethod(com.squareup.burst.ConstructorSingleNamedArgumentTest[Drink=RC_COLA])",
40 | "FINISH testMethod(com.squareup.burst.ConstructorSingleNamedArgumentTest[Drink=RC_COLA])");
41 | }
42 |
43 | @Test public void constructorMultiple() throws InitializationError {
44 | BurstJUnit4 runner = new BurstJUnit4(ConstructorMultipleArgumentTest.class);
45 | runner.run(listener.notifier());
46 | assertThat(listener.journal()).containsExactly(
47 | "START testMethod(com.squareup.burst.ConstructorMultipleArgumentTest[PEPSI, CHIPS])",
48 | "FINISH testMethod(com.squareup.burst.ConstructorMultipleArgumentTest[PEPSI, CHIPS])",
49 | "START testMethod(com.squareup.burst.ConstructorMultipleArgumentTest[PEPSI, NUTS])",
50 | "FINISH testMethod(com.squareup.burst.ConstructorMultipleArgumentTest[PEPSI, NUTS])",
51 | "START testMethod(com.squareup.burst.ConstructorMultipleArgumentTest[PEPSI, CANDY])",
52 | "FINISH testMethod(com.squareup.burst.ConstructorMultipleArgumentTest[PEPSI, CANDY])",
53 | "START testMethod(com.squareup.burst.ConstructorMultipleArgumentTest[COKE, CHIPS])",
54 | "FINISH testMethod(com.squareup.burst.ConstructorMultipleArgumentTest[COKE, CHIPS])",
55 | "START testMethod(com.squareup.burst.ConstructorMultipleArgumentTest[COKE, NUTS])",
56 | "FINISH testMethod(com.squareup.burst.ConstructorMultipleArgumentTest[COKE, NUTS])",
57 | "START testMethod(com.squareup.burst.ConstructorMultipleArgumentTest[COKE, CANDY])",
58 | "FINISH testMethod(com.squareup.burst.ConstructorMultipleArgumentTest[COKE, CANDY])",
59 | "START testMethod(com.squareup.burst.ConstructorMultipleArgumentTest[RC_COLA, CHIPS])",
60 | "FINISH testMethod(com.squareup.burst.ConstructorMultipleArgumentTest[RC_COLA, CHIPS])",
61 | "START testMethod(com.squareup.burst.ConstructorMultipleArgumentTest[RC_COLA, NUTS])",
62 | "FINISH testMethod(com.squareup.burst.ConstructorMultipleArgumentTest[RC_COLA, NUTS])",
63 | "START testMethod(com.squareup.burst.ConstructorMultipleArgumentTest[RC_COLA, CANDY])",
64 | "FINISH testMethod(com.squareup.burst.ConstructorMultipleArgumentTest[RC_COLA, CANDY])");
65 | }
66 |
67 | @Test public void constructorMultipleNames() throws InitializationError {
68 | BurstJUnit4 runner = new BurstJUnit4(ConstructorMultipleNamedArgumentTest.class);
69 | runner.run(listener.notifier());
70 | assertThat(listener.journal()).containsExactly(
71 | "START testMethod(com.squareup.burst.ConstructorMultipleNamedArgumentTest[Drink=PEPSI, CHIPS])",
72 | "FINISH testMethod(com.squareup.burst.ConstructorMultipleNamedArgumentTest[Drink=PEPSI, CHIPS])",
73 | "START testMethod(com.squareup.burst.ConstructorMultipleNamedArgumentTest[Drink=PEPSI, NUTS])",
74 | "FINISH testMethod(com.squareup.burst.ConstructorMultipleNamedArgumentTest[Drink=PEPSI, NUTS])",
75 | "START testMethod(com.squareup.burst.ConstructorMultipleNamedArgumentTest[Drink=PEPSI, CANDY])",
76 | "FINISH testMethod(com.squareup.burst.ConstructorMultipleNamedArgumentTest[Drink=PEPSI, CANDY])",
77 | "START testMethod(com.squareup.burst.ConstructorMultipleNamedArgumentTest[Drink=COKE, CHIPS])",
78 | "FINISH testMethod(com.squareup.burst.ConstructorMultipleNamedArgumentTest[Drink=COKE, CHIPS])",
79 | "START testMethod(com.squareup.burst.ConstructorMultipleNamedArgumentTest[Drink=COKE, NUTS])",
80 | "FINISH testMethod(com.squareup.burst.ConstructorMultipleNamedArgumentTest[Drink=COKE, NUTS])",
81 | "START testMethod(com.squareup.burst.ConstructorMultipleNamedArgumentTest[Drink=COKE, CANDY])",
82 | "FINISH testMethod(com.squareup.burst.ConstructorMultipleNamedArgumentTest[Drink=COKE, CANDY])",
83 | "START testMethod(com.squareup.burst.ConstructorMultipleNamedArgumentTest[Drink=RC_COLA, CHIPS])",
84 | "FINISH testMethod(com.squareup.burst.ConstructorMultipleNamedArgumentTest[Drink=RC_COLA, CHIPS])",
85 | "START testMethod(com.squareup.burst.ConstructorMultipleNamedArgumentTest[Drink=RC_COLA, NUTS])",
86 | "FINISH testMethod(com.squareup.burst.ConstructorMultipleNamedArgumentTest[Drink=RC_COLA, NUTS])",
87 | "START testMethod(com.squareup.burst.ConstructorMultipleNamedArgumentTest[Drink=RC_COLA, CANDY])",
88 | "FINISH testMethod(com.squareup.burst.ConstructorMultipleNamedArgumentTest[Drink=RC_COLA, CANDY])");
89 | }
90 |
91 | @Test public void method() throws InitializationError {
92 | BurstJUnit4 runner = new BurstJUnit4(MethodTest.class);
93 | runner.run(listener.notifier());
94 | assertThat(listener.journal()).containsExactly(
95 | "START single[PEPSI](com.squareup.burst.MethodTest)",
96 | "FINISH single[PEPSI](com.squareup.burst.MethodTest)",
97 | "START single[COKE](com.squareup.burst.MethodTest)",
98 | "FINISH single[COKE](com.squareup.burst.MethodTest)",
99 | "START single[RC_COLA](com.squareup.burst.MethodTest)",
100 | "FINISH single[RC_COLA](com.squareup.burst.MethodTest)",
101 | "START none(com.squareup.burst.MethodTest)",
102 | "FINISH none(com.squareup.burst.MethodTest)",
103 | "START multiple[PEPSI, CHIPS](com.squareup.burst.MethodTest)",
104 | "FINISH multiple[PEPSI, CHIPS](com.squareup.burst.MethodTest)",
105 | "START multiple[PEPSI, NUTS](com.squareup.burst.MethodTest)",
106 | "FINISH multiple[PEPSI, NUTS](com.squareup.burst.MethodTest)",
107 | "START multiple[PEPSI, CANDY](com.squareup.burst.MethodTest)",
108 | "FINISH multiple[PEPSI, CANDY](com.squareup.burst.MethodTest)",
109 | "START multiple[COKE, CHIPS](com.squareup.burst.MethodTest)",
110 | "FINISH multiple[COKE, CHIPS](com.squareup.burst.MethodTest)",
111 | "START multiple[COKE, NUTS](com.squareup.burst.MethodTest)",
112 | "FINISH multiple[COKE, NUTS](com.squareup.burst.MethodTest)",
113 | "START multiple[COKE, CANDY](com.squareup.burst.MethodTest)",
114 | "FINISH multiple[COKE, CANDY](com.squareup.burst.MethodTest)",
115 | "START multiple[RC_COLA, CHIPS](com.squareup.burst.MethodTest)",
116 | "FINISH multiple[RC_COLA, CHIPS](com.squareup.burst.MethodTest)",
117 | "START multiple[RC_COLA, NUTS](com.squareup.burst.MethodTest)",
118 | "FINISH multiple[RC_COLA, NUTS](com.squareup.burst.MethodTest)",
119 | "START multiple[RC_COLA, CANDY](com.squareup.burst.MethodTest)",
120 | "FINISH multiple[RC_COLA, CANDY](com.squareup.burst.MethodTest)");
121 | }
122 |
123 | @Test public void namedMethod() throws InitializationError {
124 | BurstJUnit4 runner = new BurstJUnit4(NamedMethodTest.class);
125 | runner.run(listener.notifier());
126 | assertThat(listener.journal()).containsExactly(
127 | "START single[Drink=PEPSI](com.squareup.burst.NamedMethodTest)",
128 | "FINISH single[Drink=PEPSI](com.squareup.burst.NamedMethodTest)",
129 | "START single[Drink=COKE](com.squareup.burst.NamedMethodTest)",
130 | "FINISH single[Drink=COKE](com.squareup.burst.NamedMethodTest)",
131 | "START single[Drink=RC_COLA](com.squareup.burst.NamedMethodTest)",
132 | "FINISH single[Drink=RC_COLA](com.squareup.burst.NamedMethodTest)",
133 | "START none(com.squareup.burst.NamedMethodTest)",
134 | "FINISH none(com.squareup.burst.NamedMethodTest)",
135 | "START multiple[Drink=PEPSI, CHIPS](com.squareup.burst.NamedMethodTest)",
136 | "FINISH multiple[Drink=PEPSI, CHIPS](com.squareup.burst.NamedMethodTest)",
137 | "START multiple[Drink=PEPSI, NUTS](com.squareup.burst.NamedMethodTest)",
138 | "FINISH multiple[Drink=PEPSI, NUTS](com.squareup.burst.NamedMethodTest)",
139 | "START multiple[Drink=PEPSI, CANDY](com.squareup.burst.NamedMethodTest)",
140 | "FINISH multiple[Drink=PEPSI, CANDY](com.squareup.burst.NamedMethodTest)",
141 | "START multiple[Drink=COKE, CHIPS](com.squareup.burst.NamedMethodTest)",
142 | "FINISH multiple[Drink=COKE, CHIPS](com.squareup.burst.NamedMethodTest)",
143 | "START multiple[Drink=COKE, NUTS](com.squareup.burst.NamedMethodTest)",
144 | "FINISH multiple[Drink=COKE, NUTS](com.squareup.burst.NamedMethodTest)",
145 | "START multiple[Drink=COKE, CANDY](com.squareup.burst.NamedMethodTest)",
146 | "FINISH multiple[Drink=COKE, CANDY](com.squareup.burst.NamedMethodTest)",
147 | "START multiple[Drink=RC_COLA, CHIPS](com.squareup.burst.NamedMethodTest)",
148 | "FINISH multiple[Drink=RC_COLA, CHIPS](com.squareup.burst.NamedMethodTest)",
149 | "START multiple[Drink=RC_COLA, NUTS](com.squareup.burst.NamedMethodTest)",
150 | "FINISH multiple[Drink=RC_COLA, NUTS](com.squareup.burst.NamedMethodTest)",
151 | "START multiple[Drink=RC_COLA, CANDY](com.squareup.burst.NamedMethodTest)",
152 | "FINISH multiple[Drink=RC_COLA, CANDY](com.squareup.burst.NamedMethodTest)");
153 | }
154 |
155 | @Test public void constructorAndMethod() throws InitializationError {
156 | BurstJUnit4 runner = new BurstJUnit4(ConstructorAndMethodTest.class);
157 | runner.run(listener.notifier());
158 | assertThat(listener.journal()).containsExactly(
159 | "START single[CHIPS](com.squareup.burst.ConstructorAndMethodTest[PEPSI])",
160 | "FINISH single[CHIPS](com.squareup.burst.ConstructorAndMethodTest[PEPSI])",
161 | "START single[NUTS](com.squareup.burst.ConstructorAndMethodTest[PEPSI])",
162 | "FINISH single[NUTS](com.squareup.burst.ConstructorAndMethodTest[PEPSI])",
163 | "START single[CANDY](com.squareup.burst.ConstructorAndMethodTest[PEPSI])",
164 | "FINISH single[CANDY](com.squareup.burst.ConstructorAndMethodTest[PEPSI])",
165 | "START none(com.squareup.burst.ConstructorAndMethodTest[PEPSI])",
166 | "FINISH none(com.squareup.burst.ConstructorAndMethodTest[PEPSI])",
167 | "START single[CHIPS](com.squareup.burst.ConstructorAndMethodTest[COKE])",
168 | "FINISH single[CHIPS](com.squareup.burst.ConstructorAndMethodTest[COKE])",
169 | "START single[NUTS](com.squareup.burst.ConstructorAndMethodTest[COKE])",
170 | "FINISH single[NUTS](com.squareup.burst.ConstructorAndMethodTest[COKE])",
171 | "START single[CANDY](com.squareup.burst.ConstructorAndMethodTest[COKE])",
172 | "FINISH single[CANDY](com.squareup.burst.ConstructorAndMethodTest[COKE])",
173 | "START none(com.squareup.burst.ConstructorAndMethodTest[COKE])",
174 | "FINISH none(com.squareup.burst.ConstructorAndMethodTest[COKE])",
175 | "START single[CHIPS](com.squareup.burst.ConstructorAndMethodTest[RC_COLA])",
176 | "FINISH single[CHIPS](com.squareup.burst.ConstructorAndMethodTest[RC_COLA])",
177 | "START single[NUTS](com.squareup.burst.ConstructorAndMethodTest[RC_COLA])",
178 | "FINISH single[NUTS](com.squareup.burst.ConstructorAndMethodTest[RC_COLA])",
179 | "START single[CANDY](com.squareup.burst.ConstructorAndMethodTest[RC_COLA])",
180 | "FINISH single[CANDY](com.squareup.burst.ConstructorAndMethodTest[RC_COLA])",
181 | "START none(com.squareup.burst.ConstructorAndMethodTest[RC_COLA])",
182 | "FINISH none(com.squareup.burst.ConstructorAndMethodTest[RC_COLA])");
183 | }
184 |
185 | @Test public void singleField() throws InitializationError {
186 | BurstJUnit4 runner = new BurstJUnit4(SingleFieldTest.class);
187 | runner.run(listener.notifier());
188 | assertThat(listener.journal()).containsExactly(
189 | "START testMethod(com.squareup.burst.SingleFieldTest[PEPSI])",
190 | "FINISH testMethod(com.squareup.burst.SingleFieldTest[PEPSI])",
191 | "START testMethod(com.squareup.burst.SingleFieldTest[COKE])",
192 | "FINISH testMethod(com.squareup.burst.SingleFieldTest[COKE])",
193 | "START testMethod(com.squareup.burst.SingleFieldTest[RC_COLA])",
194 | "FINISH testMethod(com.squareup.burst.SingleFieldTest[RC_COLA])");
195 | }
196 |
197 | @Test public void multipleFields() throws InitializationError {
198 | BurstJUnit4 runner = new BurstJUnit4(MultipleFieldsTest.class);
199 | runner.run(listener.notifier());
200 | assertThat(listener.journal()).containsExactly(
201 | "START testMethod(com.squareup.burst.MultipleFieldsTest[PEPSI, CHIPS])",
202 | "FINISH testMethod(com.squareup.burst.MultipleFieldsTest[PEPSI, CHIPS])",
203 | "START testMethod(com.squareup.burst.MultipleFieldsTest[PEPSI, NUTS])",
204 | "FINISH testMethod(com.squareup.burst.MultipleFieldsTest[PEPSI, NUTS])",
205 | "START testMethod(com.squareup.burst.MultipleFieldsTest[PEPSI, CANDY])",
206 | "FINISH testMethod(com.squareup.burst.MultipleFieldsTest[PEPSI, CANDY])",
207 | "START testMethod(com.squareup.burst.MultipleFieldsTest[COKE, CHIPS])",
208 | "FINISH testMethod(com.squareup.burst.MultipleFieldsTest[COKE, CHIPS])",
209 | "START testMethod(com.squareup.burst.MultipleFieldsTest[COKE, NUTS])",
210 | "FINISH testMethod(com.squareup.burst.MultipleFieldsTest[COKE, NUTS])",
211 | "START testMethod(com.squareup.burst.MultipleFieldsTest[COKE, CANDY])",
212 | "FINISH testMethod(com.squareup.burst.MultipleFieldsTest[COKE, CANDY])",
213 | "START testMethod(com.squareup.burst.MultipleFieldsTest[RC_COLA, CHIPS])",
214 | "FINISH testMethod(com.squareup.burst.MultipleFieldsTest[RC_COLA, CHIPS])",
215 | "START testMethod(com.squareup.burst.MultipleFieldsTest[RC_COLA, NUTS])",
216 | "FINISH testMethod(com.squareup.burst.MultipleFieldsTest[RC_COLA, NUTS])",
217 | "START testMethod(com.squareup.burst.MultipleFieldsTest[RC_COLA, CANDY])",
218 | "FINISH testMethod(com.squareup.burst.MultipleFieldsTest[RC_COLA, CANDY])");
219 | }
220 |
221 | @Test public void multipleNamedFields() throws InitializationError {
222 | BurstJUnit4 runner = new BurstJUnit4(MultipleNamedFieldsTest.class);
223 | runner.run(listener.notifier());
224 | assertThat(listener.journal()).containsExactly(
225 | "START testMethod(com.squareup.burst.MultipleNamedFieldsTest[Drink=PEPSI, CHIPS])",
226 | "FINISH testMethod(com.squareup.burst.MultipleNamedFieldsTest[Drink=PEPSI, CHIPS])",
227 | "START testMethod(com.squareup.burst.MultipleNamedFieldsTest[Drink=PEPSI, NUTS])",
228 | "FINISH testMethod(com.squareup.burst.MultipleNamedFieldsTest[Drink=PEPSI, NUTS])",
229 | "START testMethod(com.squareup.burst.MultipleNamedFieldsTest[Drink=PEPSI, CANDY])",
230 | "FINISH testMethod(com.squareup.burst.MultipleNamedFieldsTest[Drink=PEPSI, CANDY])",
231 | "START testMethod(com.squareup.burst.MultipleNamedFieldsTest[Drink=COKE, CHIPS])",
232 | "FINISH testMethod(com.squareup.burst.MultipleNamedFieldsTest[Drink=COKE, CHIPS])",
233 | "START testMethod(com.squareup.burst.MultipleNamedFieldsTest[Drink=COKE, NUTS])",
234 | "FINISH testMethod(com.squareup.burst.MultipleNamedFieldsTest[Drink=COKE, NUTS])",
235 | "START testMethod(com.squareup.burst.MultipleNamedFieldsTest[Drink=COKE, CANDY])",
236 | "FINISH testMethod(com.squareup.burst.MultipleNamedFieldsTest[Drink=COKE, CANDY])",
237 | "START testMethod(com.squareup.burst.MultipleNamedFieldsTest[Drink=RC_COLA, CHIPS])",
238 | "FINISH testMethod(com.squareup.burst.MultipleNamedFieldsTest[Drink=RC_COLA, CHIPS])",
239 | "START testMethod(com.squareup.burst.MultipleNamedFieldsTest[Drink=RC_COLA, NUTS])",
240 | "FINISH testMethod(com.squareup.burst.MultipleNamedFieldsTest[Drink=RC_COLA, NUTS])",
241 | "START testMethod(com.squareup.burst.MultipleNamedFieldsTest[Drink=RC_COLA, CANDY])",
242 | "FINISH testMethod(com.squareup.burst.MultipleNamedFieldsTest[Drink=RC_COLA, CANDY])");
243 | }
244 |
245 | @Test public void fieldAndMethod() throws InitializationError {
246 | BurstJUnit4 runner = new BurstJUnit4(FieldAndMethodTest.class);
247 | runner.run(listener.notifier());
248 | assertThat(listener.journal()).containsExactly(
249 | "START testMethod[PEPSI](com.squareup.burst.FieldAndMethodTest[CHIPS])",
250 | "FINISH testMethod[PEPSI](com.squareup.burst.FieldAndMethodTest[CHIPS])",
251 | "START testMethod[COKE](com.squareup.burst.FieldAndMethodTest[CHIPS])",
252 | "FINISH testMethod[COKE](com.squareup.burst.FieldAndMethodTest[CHIPS])",
253 | "START testMethod[RC_COLA](com.squareup.burst.FieldAndMethodTest[CHIPS])",
254 | "FINISH testMethod[RC_COLA](com.squareup.burst.FieldAndMethodTest[CHIPS])",
255 | "START testMethod[PEPSI](com.squareup.burst.FieldAndMethodTest[NUTS])",
256 | "FINISH testMethod[PEPSI](com.squareup.burst.FieldAndMethodTest[NUTS])",
257 | "START testMethod[COKE](com.squareup.burst.FieldAndMethodTest[NUTS])",
258 | "FINISH testMethod[COKE](com.squareup.burst.FieldAndMethodTest[NUTS])",
259 | "START testMethod[RC_COLA](com.squareup.burst.FieldAndMethodTest[NUTS])",
260 | "FINISH testMethod[RC_COLA](com.squareup.burst.FieldAndMethodTest[NUTS])",
261 | "START testMethod[PEPSI](com.squareup.burst.FieldAndMethodTest[CANDY])",
262 | "FINISH testMethod[PEPSI](com.squareup.burst.FieldAndMethodTest[CANDY])",
263 | "START testMethod[COKE](com.squareup.burst.FieldAndMethodTest[CANDY])",
264 | "FINISH testMethod[COKE](com.squareup.burst.FieldAndMethodTest[CANDY])",
265 | "START testMethod[RC_COLA](com.squareup.burst.FieldAndMethodTest[CANDY])",
266 | "FINISH testMethod[RC_COLA](com.squareup.burst.FieldAndMethodTest[CANDY])");
267 | }
268 |
269 | @Test public void namedFieldAndNamedMethod() throws InitializationError {
270 | BurstJUnit4 runner = new BurstJUnit4(NamedFieldAndNamedMethodTest.class);
271 | runner.run(listener.notifier());
272 | assertThat(listener.journal()).containsExactly(
273 | "START testMethod[Drink=PEPSI](com.squareup.burst.NamedFieldAndNamedMethodTest[Food=CHIPS])",
274 | "FINISH testMethod[Drink=PEPSI](com.squareup.burst.NamedFieldAndNamedMethodTest[Food=CHIPS])",
275 | "START testMethod[Drink=COKE](com.squareup.burst.NamedFieldAndNamedMethodTest[Food=CHIPS])",
276 | "FINISH testMethod[Drink=COKE](com.squareup.burst.NamedFieldAndNamedMethodTest[Food=CHIPS])",
277 | "START testMethod[Drink=RC_COLA](com.squareup.burst.NamedFieldAndNamedMethodTest[Food=CHIPS])",
278 | "FINISH testMethod[Drink=RC_COLA](com.squareup.burst.NamedFieldAndNamedMethodTest[Food=CHIPS])",
279 | "START testMethod[Drink=PEPSI](com.squareup.burst.NamedFieldAndNamedMethodTest[Food=NUTS])",
280 | "FINISH testMethod[Drink=PEPSI](com.squareup.burst.NamedFieldAndNamedMethodTest[Food=NUTS])",
281 | "START testMethod[Drink=COKE](com.squareup.burst.NamedFieldAndNamedMethodTest[Food=NUTS])",
282 | "FINISH testMethod[Drink=COKE](com.squareup.burst.NamedFieldAndNamedMethodTest[Food=NUTS])",
283 | "START testMethod[Drink=RC_COLA](com.squareup.burst.NamedFieldAndNamedMethodTest[Food=NUTS])",
284 | "FINISH testMethod[Drink=RC_COLA](com.squareup.burst.NamedFieldAndNamedMethodTest[Food=NUTS])",
285 | "START testMethod[Drink=PEPSI](com.squareup.burst.NamedFieldAndNamedMethodTest[Food=CANDY])",
286 | "FINISH testMethod[Drink=PEPSI](com.squareup.burst.NamedFieldAndNamedMethodTest[Food=CANDY])",
287 | "START testMethod[Drink=COKE](com.squareup.burst.NamedFieldAndNamedMethodTest[Food=CANDY])",
288 | "FINISH testMethod[Drink=COKE](com.squareup.burst.NamedFieldAndNamedMethodTest[Food=CANDY])",
289 | "START testMethod[Drink=RC_COLA](com.squareup.burst.NamedFieldAndNamedMethodTest[Food=CANDY])",
290 | "FINISH testMethod[Drink=RC_COLA](com.squareup.burst.NamedFieldAndNamedMethodTest[Food=CANDY])");
291 | }
292 | }
293 |
--------------------------------------------------------------------------------
args that apply to the underlying
79 | * constructor.
80 | */
81 | public Object[] extractConstructorArgs(final Object[] args) {
82 | return Arrays.copyOfRange(args, 0, constructor.getParameterTypes().length);
83 | }
84 |
85 | /**
86 | * @return array containing the elements of args that apply to fields.
87 | */
88 | public Object[] extractFieldArgs(final Object[] args) {
89 | return Arrays.copyOfRange(args, constructor.getParameterTypes().length, args.length);
90 | }
91 |
92 | /**
93 | * Creates a new instance by calling the underlying constructor, without initializing
94 | * any fields.
95 | */
96 | public Object newInstanceWithoutFields(Object[] args)
97 | throws IllegalAccessException, InvocationTargetException, InstantiationException {
98 | return constructor.newInstance(args);
99 | }
100 |
101 | /**
102 | * Sets the fields on an instance (as passed to
103 | * {@link TestConstructor#TestConstructor(Constructor, Field...)}) to args.
104 | * The number of arguments in the array must be equal to the number of fields.
105 | */
106 | public void initializeFieldsOnInstance(final Object instance, final Object[] args)
107 | throws IllegalAccessException {
108 | if (fields.length != args.length) {
109 | throw new IllegalArgumentException(String.format(
110 | "Requires values for %d fields, only %d values passed", fields.length, args.length));
111 | }
112 |
113 | for (int i = 0; i < fields.length; i++) {
114 | fields[i].set(instance, args[i]);
115 | }
116 | }
117 |
118 | public Annotation[][] getArgumentAnnotations() {
119 | final Annotation[][] ctorAnnotations = constructor.getParameterAnnotations();
120 | final Annotation[][] allAnnotations = new Annotation[ctorAnnotations.length + fields.length][];
121 |
122 | System.arraycopy(ctorAnnotations, 0, allAnnotations, 0, ctorAnnotations.length);
123 |
124 | for (int i = 0; i < fields.length; i++) {
125 | allAnnotations[i + ctorAnnotations.length] = fields[i].getAnnotations();
126 | }
127 |
128 | return allAnnotations;
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Burst
2 | =====
3 |
4 | A unit testing library for varying test data.
5 |
6 | **DEPRECATED**: Burst remains stable and functional, but you should check out [TestParameterInjector](https://github.com/google/TestParameterInjector) from Google which is like Burst++. Unless there are major bugs in Burst which necessitate a patch release, no new development will be occurring.
7 |
8 |
9 |
10 | Usage
11 | -----
12 |
13 | Burst is a set of test runners which rely on enums for varying both the instantiation of test
14 | classes and the methods inside of them.
15 |
16 | Define an enum for the property you wish to vary.
17 | ```java
18 | public enum Soda {
19 | PEPSI, COKE
20 | }
21 | ```
22 | The enum can be simple as above, or contain data and methods specific to what you are testing.
23 | ```java
24 | public enum Sets {
25 | HASH_SET() {
26 | @Override public