Skip to content

Commit 9b6217e

Browse files
author
Julien Poulton
committed
Merge branch 'yaml-testcases' into 'master'
feat(SDK): YAML testcases See merge request codingame/game-engine!230
2 parents 9b50b9c + cd6d4cc commit 9b6217e

File tree

4 files changed

+61
-22
lines changed

4 files changed

+61
-22
lines changed

playground/core-concepts/core-4-configuration.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ Optionally, you can tranlate your popups in French using `welcome_fr.html` files
239239

240240
You will need to create test case files to run your **Solo** game.
241241

242-
Your test cases must be named `test<number>.json` and placed in the `config` directory. Their `<number>` determine the order they will be listed in the CodinGame IDE. Here is an example:
242+
Your test cases must be named `test<number>.json` or `test<number>.yaml` and placed in the `config` directory. Their `<number>` determine the order they will be listed in the CodinGame IDE. Here is an example:
243243

244244
`test1.json`
245245
```json
@@ -253,6 +253,22 @@ Your test cases must be named `test<number>.json` and placed in the `config` dir
253253
"isValidator": "false"
254254
}
255255
```
256+
257+
or the YAML equivalent:
258+
259+
`test1.yaml`
260+
```yaml
261+
title:
262+
2: One path
263+
1: Un seul chemin
264+
testIn: |-
265+
.o...
266+
.ooo.
267+
...o.
268+
isTest: 'true'
269+
isValidator: 'false'
270+
```
271+
256272
- **title:**
257273
- **2:** English title, this parameter is mandatory.
258274
- **1:** French title, optional.

runner/pom.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1+
<project xmlns="http://maven.apache.org/POM/4.0.0"
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
23
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
34
<modelVersion>4.0.0</modelVersion>
45

@@ -45,6 +46,11 @@
4546
<artifactId>commons-lang3</artifactId>
4647
<version>3.5</version>
4748
</dependency>
49+
<dependency>
50+
<groupId>org.yaml</groupId>
51+
<artifactId>snakeyaml</artifactId>
52+
<version>1.24</version>
53+
</dependency>
4854
</dependencies>
4955

5056
</project>

runner/src/main/java/com/codingame/gameengine/runner/ConfigHelper.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public void setLeaguesDetected(boolean leaguesDetected) {
6767
}
6868
}
6969

70-
class TestCase {
70+
public static class TestCase {
7171
private Map<Integer, String> title;
7272
private String testIn;
7373
private Boolean isTest;
@@ -451,10 +451,10 @@ public GameConfig findConfig(Path rootDir) throws IOException {
451451
for (String leagueKey : questionsConfig.keySet()) {
452452
QuestionConfig questionConfig = questionsConfig.get(leagueKey);
453453
questionConfig.merge(defaultConfig);
454-
questionConfig.configDetected = isPresentConfigIni(gameConfig, questionConfig);
454+
questionConfig.configDetected = isPresentConfigIni(questionConfig);
455455
}
456456
} else {
457-
defaultConfig.configDetected = isPresentConfigIni(gameConfig, defaultConfig);
457+
defaultConfig.configDetected = isPresentConfigIni(defaultConfig);
458458
}
459459

460460
MutableInt soloQuestions = new MutableInt();
@@ -500,7 +500,7 @@ public GameConfig findConfig(Path rootDir) throws IOException {
500500
return gameConfig;
501501
}
502502

503-
private boolean isPresentConfigIni(GameConfig gameConfig, QuestionConfig questionConfig) {
503+
private boolean isPresentConfigIni(QuestionConfig questionConfig) {
504504
return questionConfig.minPlayers != null || questionConfig.maxPlayers != null;
505505
}
506506
}

runner/src/main/java/com/codingame/gameengine/runner/SoloGameRunner.java

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33
import java.io.File;
44
import java.io.IOException;
55
import java.nio.charset.StandardCharsets;
6-
import java.util.ArrayList;
76
import java.util.Arrays;
87
import java.util.List;
98

109
import org.apache.commons.io.FileUtils;
10+
import org.apache.commons.io.FilenameUtils;
11+
import org.yaml.snakeyaml.Yaml;
1112

12-
import com.google.gson.JsonObject;
13-
import com.google.gson.JsonParser;
13+
import com.codingame.gameengine.runner.ConfigHelper.TestCase;
14+
import com.google.gson.Gson;
15+
import com.google.gson.JsonSyntaxException;
1416

1517
/**
1618
* The class to use to run local games and display the replay in a webpage on a temporary local server.
@@ -27,18 +29,33 @@ public SoloGameRunner() {
2729
}
2830

2931
private List<String> getLinesFromTestCaseFile(File file) {
30-
List<String> lines = new ArrayList<>();
32+
TestCase testCase;
3133
try {
32-
JsonObject testCaseJson = new JsonParser().parse(FileUtils.readFileToString(file, StandardCharsets.UTF_8)).getAsJsonObject();
33-
lines.addAll(Arrays.asList(testCaseJson.get("testIn").getAsString().split("\\n")));
34+
testCase = parseTestCaseFile(file);
3435
} catch (IOException e) {
35-
throw new RuntimeException("Cannot read file", e);
36-
} catch (NullPointerException e) {
37-
throw new RuntimeException("Cannot find \"testIn\" property");
36+
throw new RuntimeException("Cannot read file " + file.getName(), e);
3837
} catch (Exception e) {
39-
throw new RuntimeException("Cannot parse file", e);
38+
throw new RuntimeException("Cannot parse file " + file.getName(), e);
39+
}
40+
41+
if (testCase.getTestIn() == null) {
42+
throw new RuntimeException("Cannot find \"testIn\" property");
43+
}
44+
45+
return Arrays.asList(testCase.getTestIn().split("\\n"));
46+
}
47+
48+
private TestCase parseTestCaseFile(File file) throws JsonSyntaxException, IOException {
49+
String extension = FilenameUtils.getExtension(file.getName());
50+
51+
switch (extension.toLowerCase()) {
52+
case "yaml":
53+
case "yml":
54+
return new Yaml().loadAs(FileUtils.readFileToString(file, StandardCharsets.UTF_8), TestCase.class);
55+
case "json":
56+
default:
57+
return new Gson().fromJson(FileUtils.readFileToString(file, StandardCharsets.UTF_8), TestCase.class);
4058
}
41-
return lines;
4259
}
4360

4461
/**
@@ -47,7 +64,7 @@ private List<String> getLinesFromTestCaseFile(File file) {
4764
* The file path must be relative considering the root directory is <b>config</b>.
4865
*
4966
* @param testCaseFileName
50-
* the test case file path
67+
* the test case file path (JSON or YAML)
5168
*/
5269
public void setTestCase(String testCaseFileName) {
5370
setTestCase(new File(System.getProperty("user.dir")).toPath().resolve("config/" + testCaseFileName).toFile());
@@ -57,7 +74,7 @@ public void setTestCase(String testCaseFileName) {
5774
* Sets a test case file which <b>testIn</b> value will be sent to the Game Manager as a test case input.
5875
*
5976
* @param testCaseFile
60-
* the test case file
77+
* the test case file (JSON or YAML)
6178
*/
6279
public void setTestCase(File testCaseFile) {
6380
if (testCaseFile == null) {
@@ -66,10 +83,10 @@ public void setTestCase(File testCaseFile) {
6683
if (!testCaseFile.isFile()) {
6784
throw new RuntimeException("Given test case is not a file " + testCaseFile.getAbsolutePath());
6885
}
69-
86+
7087
setTestCaseInput(getLinesFromTestCaseFile(testCaseFile));
7188
}
72-
89+
7390
/**
7491
* Sets a list of <code>String</code> as a test case input that will be sent to the Game Manager.
7592
*
@@ -79,7 +96,7 @@ public void setTestCase(File testCaseFile) {
7996
public void setTestCaseInput(List<String> testCaseInput) {
8097
this.testCaseInput = testCaseInput;
8198
}
82-
99+
83100
/**
84101
* Sets a <code>String</code> as a test case input that will be sent to the Game Manager.
85102
* <p>

0 commit comments

Comments
 (0)