Skip to content

Commit 7264159

Browse files
committed
Porting ruby implementation
1 parent 99a37f1 commit 7264159

File tree

7 files changed

+298
-104
lines changed

7 files changed

+298
-104
lines changed

src/main/java/org/teachingextensions/approvals/lite/Approvals.java

Lines changed: 61 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -14,67 +14,76 @@
1414
import java.util.Arrays;
1515

1616
public class Approvals {
17-
public static void verify(String response) throws Exception {
18-
verify(new ApprovalTextWriter(response, "txt"), FileTypes.Text);
19-
}
17+
public static void verify(String response) throws Exception {
18+
verify(new ApprovalTextWriter(response, "txt"), FileTypes.Text);
19+
}
2020

21-
public static <T> void verifyAll(String header, T[] values,
22-
Function1<T, String> f1) {
23-
verifyAll(header, Arrays.asList(values), f1);
24-
}
21+
public static <T> void verifyAll(String header, T[] values) {
22+
Approvals.verifyAll(header, Arrays.asList(values), new Function1<T, String>() {
23+
@Override
24+
public String call(T i) {
25+
return i + "";
26+
}
27+
});
28+
}
2529

26-
public static <T> void verifyAll(String header, Iterable<T> array,
27-
Function1<T, String> f1) {
28-
String text = formatHeader(header) + ArrayUtils.toString(array, f1);
29-
verify(new ApprovalTextWriter(text, "txt"), FileTypes.Text);
30-
}
30+
public static <T> void verifyAll(String header, T[] values,
31+
Function1<T, String> f1) {
32+
verifyAll(header, Arrays.asList(values), f1);
33+
}
3134

32-
private static String formatHeader(String header) {
33-
return StringUtils.isEmpty(header) ? "" : header + "\r\n\r\n\r\n";
34-
}
35+
public static <T> void verifyAll(String header, Iterable<T> array,
36+
Function1<T, String> f1) {
37+
String text = formatHeader(header) + ArrayUtils.toString(array, f1);
38+
verify(new ApprovalTextWriter(text, "txt"), FileTypes.Text);
39+
}
3540

36-
public static void verifyHtml(String response) throws Exception {
37-
verify(new ApprovalTextWriter(response, "html"), FileTypes.Html);
38-
}
41+
private static String formatHeader(String header) {
42+
return StringUtils.isEmpty(header) ? "" : header + "\r\n\r\n\r\n";
43+
}
3944

40-
public static void verify(BufferedImage bufferedImage) {
41-
verify(new ImageApprovalWriter(bufferedImage), FileTypes.Image);
42-
}
45+
public static void verifyHtml(String response) throws Exception {
46+
verify(new ApprovalTextWriter(response, "html"), FileTypes.Html);
47+
}
4348

44-
public static void verify(ApprovalWriter writer, ApprovalNamer namer,
45-
ApprovalFailureReporter reporter) {
46-
verify(new FileApprover(writer, namer), reporter);
47-
}
49+
public static void verify(BufferedImage bufferedImage) {
50+
verify(new ImageApprovalWriter(bufferedImage), FileTypes.Image);
51+
}
4852

49-
public static void verify(ApprovalWriter writer, String fileType) {
50-
verify(writer, createApprovalNamer(), ReporterFactory.get(fileType));
51-
}
53+
public static void verify(ApprovalWriter writer, ApprovalNamer namer,
54+
ApprovalFailureReporter reporter) {
55+
verify(new FileApprover(writer, namer), reporter);
56+
}
57+
58+
public static void verify(ApprovalWriter writer, String fileType) {
59+
verify(writer, createApprovalNamer(), ReporterFactory.get(fileType));
60+
}
5261

53-
public static void verify(FileApprover approver,
54-
ApprovalFailureReporter reporter) {
55-
try {
56-
if (!approver.approve()) {
57-
boolean passed = false;
58-
if (reporter instanceof ApprovalFailureOverrider) {
59-
passed = approver
60-
.askToChangeReceivedToApproved((ApprovalFailureOverrider) reporter);
61-
}
62-
if (!passed) {
63-
approver.reportFailure(reporter);
64-
approver.fail();
65-
} else {
66-
approver.cleanUpAfterSuccess(reporter);
67-
}
68-
} else {
69-
approver.cleanUpAfterSuccess(reporter);
70-
}
71-
} catch (Exception e) {
72-
throw ObjectUtils.throwAsError(e);
62+
public static void verify(FileApprover approver,
63+
ApprovalFailureReporter reporter) {
64+
try {
65+
if (!approver.approve()) {
66+
boolean passed = false;
67+
if (reporter instanceof ApprovalFailureOverrider) {
68+
passed = approver
69+
.askToChangeReceivedToApproved((ApprovalFailureOverrider) reporter);
7370
}
71+
if (!passed) {
72+
approver.reportFailure(reporter);
73+
approver.fail();
74+
} else {
75+
approver.cleanUpAfterSuccess(reporter);
76+
}
77+
} else {
78+
approver.cleanUpAfterSuccess(reporter);
79+
}
80+
} catch (Exception e) {
81+
throw ObjectUtils.throwAsError(e);
7482
}
83+
}
7584

76-
public static ApprovalNamer createApprovalNamer() {
77-
return new JUnitStackTraceNamer();
78-
}
85+
public static ApprovalNamer createApprovalNamer() {
86+
return new JUnitStackTraceNamer();
87+
}
7988

80-
}
89+
}

src/main/java/org/teachingextensions/approvals/lite/util/ArrayUtils.java

Lines changed: 52 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -8,68 +8,68 @@
88
* A static class of convenience methods for arrays and collections.
99
*/
1010
public class ArrayUtils {
11-
public static <T> java.util.Collection<T> addArray(java.util.Collection<T> v, T array[]) {
12-
if ((array == null) || (v == null)) {
13-
return v;
14-
}
15-
Collections.addAll(v, array);
16-
return v;
11+
public static <T> java.util.Collection<T> addArray(java.util.Collection<T> v, T array[]) {
12+
if ((array == null) || (v == null)) {
13+
return v;
1714
}
15+
Collections.addAll(v, array);
16+
return v;
17+
}
1818

19-
public static <T> String toString(T[] values, Function1<T, String> formatter) {
20-
return toString(Arrays.asList(values), formatter);
21-
}
19+
public static <T> String toString(T[] values, Function1<T, String> formatter) {
20+
return toString(Arrays.asList(values), formatter);
21+
}
2222

23-
public static <T> String toString(Iterable<T> values, Function1<T, String> formatter) {
24-
StringBuilder b = new StringBuilder();
25-
for (T t : values) {
26-
b.append(formatter.call(t)).append("\r\n");
27-
}
28-
return b.toString();
23+
public static <T> String toString(Iterable<T> values, Function1<T, String> formatter) {
24+
StringBuilder b = new StringBuilder();
25+
for (T t : values) {
26+
b.append(formatter.call(t)).append("\r\n");
2927
}
28+
return b.toString();
29+
}
3030

31-
public static <T> T[] toReverseArray(T[] array) {
32-
for (int i = 0; i < array.length / 2; i++) {
33-
T o1 = array[i];
34-
int end = array.length - i - 1;
35-
T o2 = array[end];
36-
array[i] = o2;
37-
array[end] = o1;
38-
}
39-
return array;
31+
public static <T> T[] toReverseArray(T[] array) {
32+
for (int i = 0; i < array.length / 2; i++) {
33+
T o1 = array[i];
34+
int end = array.length - i - 1;
35+
T o2 = array[end];
36+
array[i] = o2;
37+
array[end] = o1;
4038
}
39+
return array;
40+
}
4141

42-
public static boolean isEmpty(Object[] array) {
43-
return ((array == null) || (array.length == 0));
44-
}
42+
public static boolean isEmpty(Object[] array) {
43+
return ((array == null) || (array.length == 0));
44+
}
4545

46-
public static <H, T extends H> T getFirst(T[] array, Comparator<H> comparator) {
47-
return get(array, comparator, true);
48-
}
46+
public static <H, T extends H> T getFirst(T[] array, Comparator<H> comparator) {
47+
return get(array, comparator, true);
48+
}
4949

50-
private static <H, T extends H> T get(T[] array, Comparator<H> sorter, boolean wantFirst) {
51-
if (isEmpty(array)) {
52-
return null;
53-
}
54-
T last = array[0];
55-
for (int i = 1; i < array.length; i++) {
56-
int compare = sorter.compare(last, array[i]);
57-
if ((wantFirst && compare > 0) || (!wantFirst && compare < 0)) {
58-
last = array[i];
59-
}
60-
}
61-
return last;
50+
private static <H, T extends H> T get(T[] array, Comparator<H> sorter, boolean wantFirst) {
51+
if (isEmpty(array)) {
52+
return null;
6253
}
63-
64-
public static <T> T getLast(List<T> list) {
65-
return list.get(list.size() - 1);
54+
T last = array[0];
55+
for (int i = 1; i < array.length; i++) {
56+
int compare = sorter.compare(last, array[i]);
57+
if ((wantFirst && compare > 0) || (!wantFirst && compare < 0)) {
58+
last = array[i];
59+
}
6660
}
61+
return last;
62+
}
6763

68-
public static <T> List<T> combine(List<T> list1, List<T> list2) {
69-
List<T> all = new ArrayList<>();
70-
all.addAll(list1);
71-
all.addAll(list2);
72-
return all;
73-
}
64+
public static <T> T getLast(List<T> list) {
65+
return list.get(list.size() - 1);
66+
}
67+
68+
public static <T> List<T> combine(List<T> list1, List<T> list2) {
69+
List<T> all = new ArrayList<>();
70+
all.addAll(list1);
71+
all.addAll(list2);
72+
return all;
73+
}
7474

75-
}
75+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package org.teachingextensions.logo;
2+
3+
import java.util.Arrays;
4+
5+
/**
6+
* A nine-puzzle
7+
*
8+
* @see <a href="http://en.wikipedia.org/wiki/15_puzzle">Wikipedia</a>
9+
*/
10+
public class Puzzle {
11+
private static final int[] solution = {0, 1, 2, 3, 4, 5, 6, 7, 8};
12+
private static final int blank = 8;
13+
private final int[] cells;
14+
15+
public Puzzle(int[] cells) {
16+
this.cells = cells;
17+
}
18+
19+
public boolean isSolved() {
20+
for (int i = 0; i < solution.length; i++) {
21+
if (solution[i] != cells[i]) {
22+
return false;
23+
}
24+
}
25+
return true;
26+
}
27+
28+
public int getBlankIndex() {
29+
for (int i = 0; i < cells.length; i++) {
30+
if (cells[i] == blank) {
31+
return i;
32+
}
33+
}
34+
return -1;
35+
}
36+
37+
/**
38+
* Create a copy of the puzzle where the blank swapped with the value in the target position
39+
* @param target move the blank to this location, and move the value from this location to the current blank location
40+
* @return A copy of the puzzle with the blank and target swapped.
41+
*/
42+
public Puzzle swapBlank(int target) {
43+
int[] copy = Arrays.copyOf(cells, cells.length);
44+
int x = copy[target];
45+
copy[getBlankIndex()] = x;
46+
copy[target] = 8;
47+
return new Puzzle(copy);
48+
}
49+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package org.teachingextensions.logo;
2+
3+
/**
4+
* Represents a node in the puzzle-solving graph. Keeps track of the current puzzle arrangement and the actions
5+
* required to arrive at the current arrangement from the starting arrangement.
6+
*/
7+
public class PuzzleState {
8+
public enum Directions {
9+
Left(-1), Right(1), Up(-3), Down(3);
10+
11+
private final int value;
12+
13+
private Directions(int i) {
14+
this.value = i;
15+
}
16+
17+
public int getValue() {
18+
return value;
19+
}
20+
21+
@Override
22+
public String toString() {
23+
return "{" + super.toString() + " = " + value + '}';
24+
}
25+
}
26+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.teachingextensions.logo;
2+
3+
import org.junit.Test;
4+
import org.teachingextensions.approvals.lite.Approvals;
5+
import org.teachingextensions.approvals.lite.reporters.FileLauncherReporter;
6+
import org.teachingextensions.approvals.lite.reporters.UseReporter;
7+
8+
@UseReporter(FileLauncherReporter.class)
9+
public class PuzzleStateTest {
10+
11+
/**
12+
* The state can tell you what moves are allowed from cell to cell
13+
*/
14+
@Test
15+
public void state_has_move_directions(){
16+
StringBuilder b = new StringBuilder();
17+
Approvals.verifyAll("Directions", PuzzleState.Directions.values());
18+
}
19+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Directions
2+
3+
4+
{Left = -1}
5+
{Right = 1}
6+
{Up = -3}
7+
{Down = 3}

0 commit comments

Comments
 (0)