Skip to content

Commit d57c016

Browse files
author
Julien Letrouit
committed
Added for loops and arrays bonus koans
1 parent 278ef06 commit d57c016

14 files changed

Lines changed: 1356 additions & 76 deletions

src/main/java/bonuses/english/AboutArrays.java

Lines changed: 407 additions & 0 deletions
Large diffs are not rendered by default.

src/main/java/bonuses/french/AboutArrays.java

Lines changed: 407 additions & 0 deletions
Large diffs are not rendered by default.

src/main/java/engine/Assertions.java

Lines changed: 69 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import java.util.function.Function;
88

99
import engine.ConsoleFmt.Formats;
10+
import engine.ConsoleFmt.Formatted;
11+
import engine.script.Expression;
1012
import engine.script.Type;
1113

1214
import static engine.ConsoleFmt.code;
@@ -103,77 +105,126 @@ public static ResultAssertion assertAskedInStdIn() {
103105
public static ResultAssertion assertReturnValueEquals(final int expected) {
104106
return (p, res) -> {
105107
if (res.executionResult == null) {
106-
p.println(format(EXPECTED_TO_RETURN_INT_BUT_RETURNED_NULL, Formats.Red, code(res.resultExpressionSourceCode), code(expected)));
108+
p.println(format(EXPECTED_TO_RETURN_BUT_RETURNED_NULL, Formats.Red, code(res.resultExpressionSourceCode), code(expected)));
107109
return false;
108110
} else if (!(res.executionResult instanceof Integer)) {
109111
p.println(format(EXPECTED_TO_RETURN_INT_BUT_RETURNED_OTHER_TYPE, Formats.Red, code(res.resultExpressionSourceCode), code(res.executionResult.getClass().getSimpleName())));
110112
return false;
111113
} else if (((Integer)res.executionResult).intValue() != expected) {
112-
p.println(format(EXPECTED_TO_RETURN_INT_BUT_RETURNED, Formats.Red, code(res.resultExpressionSourceCode), code(Integer.toString(expected)), code(res.executionResult.toString())));
114+
p.println(format(EXPECTED_TO_RETURN_BUT_RETURNED, Formats.Red, code(res.resultExpressionSourceCode), code(Integer.toString(expected)), code(res.executionResult.toString())));
113115
return false;
114116
}
115117

116-
p.println(format(OK_RETURNED_INT, Formats.Green, code(res.resultExpressionSourceCode), code(expected)));
118+
p.println(format(OK_RETURNED, Formats.Green, code(res.resultExpressionSourceCode), code(expected)));
119+
return true;
120+
};
121+
}
122+
123+
public static ResultAssertion assertReturnValueEquals(final int[] expected) {
124+
return (p, res) -> {
125+
final Formatted<String> expectedFmted = code(Expression.formatLiteralSourceCode(expected));
126+
if (res.executionResult == null) {
127+
p.println(format(EXPECTED_TO_RETURN_BUT_RETURNED_NULL, Formats.Red, code(res.resultExpressionSourceCode), expectedFmted));
128+
return false;
129+
} else if (!(res.executionResult instanceof int[])) {
130+
p.println(format(EXPECTED_TO_RETURN_INT_ARRAY_BUT_RETURNED_OTHER_TYPE, Formats.Red, code(res.resultExpressionSourceCode), code(res.executionResult.getClass().getSimpleName())));
131+
return false;
132+
} else if (!Arrays.equals(expected, (int[])res.executionResult)) {
133+
p.println(format(EXPECTED_TO_RETURN_BUT_RETURNED, Formats.Red, code(res.resultExpressionSourceCode), expectedFmted, code(Expression.formatLiteralSourceCode((int[])res.executionResult))));
134+
return false;
135+
}
136+
137+
p.println(format(OK_RETURNED, Formats.Green, code(res.resultExpressionSourceCode), expectedFmted));
117138
return true;
118139
};
119140
}
120141

121142
private static final double EPSILON = 0.0000000001;
122-
private static boolean equals(Double actual, double expected) {
123-
var diff = Math.abs(actual.doubleValue() - expected);
124-
return diff < EPSILON;
143+
private static boolean eq(Object expected, Object actual) {
144+
if (actual == null) {
145+
return expected == null;
146+
} else if (expected instanceof int[] aIntArr && actual instanceof int[] bIntArr) {
147+
return Arrays.equals(aIntArr, bIntArr);
148+
} else if (expected instanceof Double aDouble && actual instanceof Double bDouble) {
149+
final var diff = Math.abs(aDouble.doubleValue() - bDouble);
150+
return diff < EPSILON;
151+
}
152+
return actual.equals(expected);
153+
}
154+
155+
public static ResultAssertion assertVariableEquals(final String variableName, final Object expected) {
156+
return (p, res) -> {
157+
final Object val = res.executionContext.getVariableValue(variableName);
158+
final Formatted<String> expectedFmted = code(Expression.formatLiteralSourceCode(expected));
159+
final Formatted<String> actualFmted = code(Expression.formatLiteralSourceCode(val));
160+
if (val == null) {
161+
p.println(format(EXPECTED_VARIABLE_TO_EQUAL_BUT_IS_NULL, Formats.Red, code(res.resultExpressionSourceCode), code(variableName), expectedFmted));
162+
return false;
163+
} else if (val.getClass() != expected.getClass()) {
164+
p.println(format(EXPECTED_VARIABLE_TO_BE_BUT_WAS_OTHER_TYPE, Formats.Red, code(res.resultExpressionSourceCode), code(variableName), code(expected.getClass().getSimpleName()), code(val.getClass().getSimpleName())));
165+
return false;
166+
} else if (!eq(expected, val)) {
167+
p.println(format(EXPECTED_VARIABLE_TO_EQUAL_BUT_EQUAL, Formats.Red, code(res.resultExpressionSourceCode), code(variableName), expectedFmted, actualFmted));
168+
return false;
169+
}
170+
171+
p.println(format(OK_VARIABLE_EQUAL, Formats.Green, code(variableName), expectedFmted));
172+
return true;
173+
};
125174
}
126175

127176
public static ResultAssertion assertReturnValueEquals(final double expected) {
128177
return (p, res) -> {
129178
if (res.executionResult == null) {
130-
p.println(format(EXPECTED_TO_RETURN_DOUBLE_BUT_RETURNED_NULL, Formats.Red, res.resultExpressionSourceCode, expected));
179+
p.println(format(EXPECTED_TO_RETURN_BUT_RETURNED_NULL, Formats.Red, res.resultExpressionSourceCode, expected));
131180
return false;
132181
} else if (!(res.executionResult instanceof Double)) {
133182
p.println(format(EXPECTED_TO_RETURN_DOUBLE_BUT_RETURNED_OTHER_TYPE, Formats.Red, code(res.resultExpressionSourceCode), res.executionResult.getClass().getSimpleName()));
134183
return false;
135-
} else if (!equals((Double)res.executionResult, expected)) {
136-
p.println(format(EXPECTED_TO_RETURN_DOUBLE_BUT_RETURNED, Formats.Red, res.resultExpressionSourceCode, expected, ((Double)res.executionResult).doubleValue()));
184+
} else if (!eq(res.executionResult, expected)) {
185+
p.println(format(EXPECTED_TO_RETURN_BUT_RETURNED, Formats.Red, res.resultExpressionSourceCode, expected, ((Double)res.executionResult).doubleValue()));
137186
return false;
138187
}
139188

140-
p.println(format(OK_RETURNED_DOUBLE, Formats.Green, code(res.resultExpressionSourceCode), code(expected)));
189+
p.println(format(OK_RETURNED, Formats.Green, code(res.resultExpressionSourceCode), code(expected)));
141190
return true;
142191
};
143192
}
144193

145194
public static ResultAssertion assertReturnValueEquals(final boolean expected) {
146195
return (p, res) -> {
147196
if (res.executionResult == null) {
148-
p.println(format(EXPECTED_TO_RETURN_BOOLEAN_BUT_RETURNED_NULL, Formats.Red, res.resultExpressionSourceCode, expected));
197+
p.println(format(EXPECTED_TO_RETURN_BUT_RETURNED_NULL, Formats.Red, res.resultExpressionSourceCode, expected));
149198
return false;
150199
} else if (!(res.executionResult instanceof Boolean)) {
151200
p.println(format(EXPECTED_TO_RETURN_BOOLEAN_BUT_RETURNED_OTHER_TYPE, Formats.Red, code(res.resultExpressionSourceCode), res.executionResult.getClass().getSimpleName()));
152201
return false;
153202
} else if (((Boolean)res.executionResult).booleanValue() != expected) {
154-
p.println(format(EXPECTED_TO_RETURN_BOOLEAN_BUT_RETURNED, Formats.Red, res.resultExpressionSourceCode, expected, ((Boolean)res.executionResult).booleanValue()));
203+
p.println(format(EXPECTED_TO_RETURN_BUT_RETURNED, Formats.Red, res.resultExpressionSourceCode, expected, ((Boolean)res.executionResult).booleanValue()));
155204
return false;
156205
}
157206

158-
p.println(format(OK_RETURNED_BOOLEAN, Formats.Green, code(res.resultExpressionSourceCode), code(expected)));
207+
p.println(format(OK_RETURNED, Formats.Green, code(res.resultExpressionSourceCode), code(expected)));
159208
return true;
160209
};
161210
}
162211

163212
public static ResultAssertion assertReturnValueEquals(final Localizable<String> expected) {
164213
return (p, res) -> {
214+
final Formatted<String> expectedFmted = code(Expression.formatLiteralSourceCode(expected.get(res.locale)));
215+
final Formatted<String> actualFmted = code(Expression.formatLiteralSourceCode(res.executionResult));
165216
if (res.executionResult == null) {
166-
p.println(format(EXPECTED_TO_RETURN_STRING_BUT_RETURNED_NULL, Formats.Red, res.resultExpressionSourceCode, expected.get(res.locale)));
217+
p.println(format(EXPECTED_TO_RETURN_BUT_RETURNED_NULL, Formats.Red, res.resultExpressionSourceCode, expectedFmted));
167218
return false;
168219
} else if (!(res.executionResult instanceof String)) {
169220
p.println(format(EXPECTED_TO_RETURN_STRING_BUT_RETURNED_OTHER_TYPE, Formats.Red, code(res.resultExpressionSourceCode), res.executionResult.getClass().getSimpleName()));
170221
return false;
171222
} else if (!((String)res.executionResult).equals(expected.get(res.locale))) {
172-
p.println(format(EXPECTED_TO_RETURN_STRING_BUT_RETURNED, Formats.Red, res.resultExpressionSourceCode, expected.get(res.locale), (String)res.executionResult));
223+
p.println(format(EXPECTED_TO_RETURN_BUT_RETURNED, Formats.Red, res.resultExpressionSourceCode,expectedFmted, actualFmted));
173224
return false;
174225
}
175226

176-
p.println(format(OK_RETURNED_STRING, Formats.Green, code(res.resultExpressionSourceCode), code(expected.get(res.locale))));
227+
p.println(format(OK_RETURNED, Formats.Green, code(res.resultExpressionSourceCode), expectedFmted));
177228
return true;
178229
};
179230
}
@@ -200,7 +251,7 @@ public static ResultAssertion assertReturnValueWithRandomEquals(final DoubleToIn
200251
return (p, res) -> {
201252
final var randomNumber = res.randomNumber();
202253
if (res.executionResult == null) {
203-
p.println(format(EXPECTED_TO_RETURN_INT_BUT_RETURNED_NULL, Formats.Red, res.resultExpressionSourceCode, expected.applyAsInt(randomNumber)));
254+
p.println(format(EXPECTED_TO_RETURN_BUT_RETURNED_NULL, Formats.Red, res.resultExpressionSourceCode, expected.applyAsInt(randomNumber)));
204255
return false;
205256
} else if (!(res.executionResult instanceof Integer)) {
206257
p.println(format(EXPECTED_TO_RETURN_INT_BUT_RETURNED_OTHER_TYPE, Formats.Red, res.resultExpressionSourceCode, res.executionResult.getClass().getSimpleName()));
@@ -250,7 +301,7 @@ private static ResultAssertion assertReturnValueWithRandomEquals(final Function<
250301

251302
final int expected = buildExpected.apply(res);
252303
if (res.executionResult == null) {
253-
p.println(format(EXPECTED_TO_RETURN_INT_BUT_RETURNED_NULL, Formats.Red, res.resultExpressionSourceCode, expected));
304+
p.println(format(EXPECTED_TO_RETURN_BUT_RETURNED_NULL, Formats.Red, res.resultExpressionSourceCode, expected));
254305
return false;
255306
} else if (!(res.executionResult instanceof Integer)) {
256307
p.println(format(EXPECTED_TO_RETURN_INT_BUT_RETURNED_OTHER_TYPE, Formats.Red, res.resultExpressionSourceCode, res.executionResult.getClass().getSimpleName()));

src/main/java/engine/KoanResult.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import java.util.Optional;
44

5+
import engine.script.ExecutionContext;
6+
57
/**
68
* Stores all the information about what happened during the execution of a koan.
79
*/
@@ -11,19 +13,21 @@ public final class KoanResult {
1113
private final String[] stdInLines;
1214
private int stdInIndex = 0;
1315
public final Object executionResult;
16+
public final ExecutionContext executionContext;
1417
/**
1518
* The source code of the last script expression, the one we are actually asserting the result and/or the console output.
1619
*/
1720
public final String resultExpressionSourceCode;
1821
public final KoanTest test;
1922
public final Locale locale;
2023

21-
public KoanResult(final Locale locale, final KoanTest test, final String[] stdOutLines, final String[] stdInLines, final Object executionResult) {
24+
public KoanResult(final Locale locale, final KoanTest test, final String[] stdOutLines, final String[] stdInLines, final Object executionResult, final ExecutionContext executionContext) {
2225
this.locale = locale;
2326
this.test = test;
2427
this.stdOutLines = stdOutLines;
2528
this.stdInLines = stdInLines;
2629
this.executionResult = executionResult;
30+
this.executionContext = executionContext;
2731
resultExpressionSourceCode = test.script[test.script.length - 1].formatSourceCode(locale);
2832
}
2933

src/main/java/engine/Sensei.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ private boolean executeCall(final KoanTest test) {
146146
test,
147147
interceptionResult.stdOutLines,
148148
interceptionResult.stdInLines,
149-
interceptionResult.returnValue
149+
interceptionResult.returnValue.executionResult(),
150+
interceptionResult.returnValue.context()
150151
);
151152

152153
concludeConsole(test.koan);

src/main/java/engine/TestSensei.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public void displayOutputToConsole() {
1919
}
2020

2121
public String toString() {
22-
return String.format("%s/%s[%d]", test.koan.koanClass.get(TEST_LOCALE).simpleClassName, test.koan.koanName, testIndex);
22+
return String.format("%s/%s[%d]", test.koan.koanClass.get(TEST_LOCALE).simpleClassName, test.koan.koanName.get(TEST_LOCALE), testIndex);
2323
}
2424
}
2525

@@ -60,7 +60,8 @@ private static TestResult executeTest(final KoanTestIndex testIndex) {
6060
test,
6161
interceptionResult.stdOutLines,
6262
interceptionResult.stdInLines,
63-
interceptionResult.returnValue
63+
interceptionResult.returnValue.executionResult(),
64+
interceptionResult.returnValue.context()
6465
);
6566

6667
return testIndex.toResult(result.executeAssertions(capturingPrinter), capturingPrinter);

0 commit comments

Comments
 (0)