Skip to content

Commit 658b06b

Browse files
author
Arun Prasaad
committed
Add a test for the save button
1 parent f8483e2 commit 658b06b

File tree

3 files changed

+137
-43
lines changed

3 files changed

+137
-43
lines changed

src/main/java/ihm/Editor.java

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,25 +33,29 @@ enum Component {
3333
WALL_BUTTON,
3434
TARGET_BUTTON,
3535
EMPTY_BUTTON,
36-
36+
3737
// Action buttons
3838
SAVE_BUTTON,
3939
BACK_BUTTON,
4040
QUIT_BUTTON,
41-
41+
4242
// Other components
4343
ERROR_LABEL,
4444
SOKOBAN_PANEL
4545
}
4646
private static final Logger LOGGER = Logger.getLogger(Editor.class.getName());
4747

48-
private static final int TILE_SIZE = 32;
48+
@VisibleForTesting
49+
static final int TILE_SIZE = 32;
50+
51+
@VisibleForTesting
52+
static final int X_OFFSET = 10; // Horizontal offset from window edge to grid start
4953

5054
private int windowWidth = 0;
5155
private int windowHeight = 0;
5256
private final Controller controller;
5357
private TileType content = TileType.OUTSIDE;
54-
58+
5559
@VisibleForTesting
5660
TileType getContent() {
5761
return content;
@@ -228,7 +232,7 @@ private void createQuitButton(String name) {
228232
});
229233
this.add(quit);
230234
}
231-
235+
232236
@VisibleForTesting
233237
ExitHandler defaultExitHandler() {
234238
return System::exit;
@@ -239,7 +243,7 @@ private void createPlayerButton() {
239243
button.setName(Component.PLAYER_BUTTON.name());
240244
button.setOpaque(false);
241245
button.setContentAreaFilled(false);
242-
button.setBounds(windowWidth + 30, 0, 32, 32);
246+
button.setBounds(windowWidth + 30, 0, TILE_SIZE, TILE_SIZE);
243247
button.addActionListener(_ -> content = TileType.WORKER_ON_FLOOR);
244248
this.add(button);
245249
}
@@ -249,7 +253,7 @@ private void createBackgroundButton() {
249253
button.setName(Component.BACKGROUND_BUTTON.name());
250254
button.setOpaque(false);
251255
button.setContentAreaFilled(false);
252-
button.setBounds(windowWidth + 30, 37, 32, 32);
256+
button.setBounds(windowWidth + 30, 37, TILE_SIZE, TILE_SIZE);
253257
button.addActionListener(_ -> content = TileType.OUTSIDE);
254258
this.add(button);
255259
}
@@ -259,7 +263,7 @@ private void createBoxButton() {
259263
button.setName(Component.BOX_BUTTON.name());
260264
button.setOpaque(false);
261265
button.setContentAreaFilled(false);
262-
button.setBounds(windowWidth + 30, 74, 32, 32);
266+
button.setBounds(windowWidth + 30, 74, TILE_SIZE, TILE_SIZE);
263267
button.addActionListener(_ -> content = TileType.UNSTORED_BOX);
264268
this.add(button);
265269
}
@@ -269,7 +273,7 @@ private void createBoxOnTargetButton() {
269273
button.setName(Component.BOX_ON_TARGET_BUTTON.name());
270274
button.setOpaque(false);
271275
button.setContentAreaFilled(false);
272-
button.setBounds(windowWidth + 30, 111, 32, 32);
276+
button.setBounds(windowWidth + 30, 111, TILE_SIZE, TILE_SIZE);
273277
button.addActionListener(_ -> content = TileType.STORED_BOX);
274278
this.add(button);
275279
}
@@ -279,7 +283,7 @@ private void createPlayerOnTargetButton() {
279283
button.setName(Component.PLAYER_ON_TARGET_BUTTON.name());
280284
button.setOpaque(false);
281285
button.setContentAreaFilled(false);
282-
button.setBounds(windowWidth + 75, 0, 32, 32);
286+
button.setBounds(windowWidth + 75, 0, TILE_SIZE, TILE_SIZE);
283287
button.addActionListener(_ -> content = TileType.WORKER_IN_STORAGE_AREA);
284288
this.add(button);
285289
}
@@ -289,7 +293,7 @@ private void createWallButton() {
289293
button.setName(Component.WALL_BUTTON.name());
290294
button.setOpaque(false);
291295
button.setContentAreaFilled(false);
292-
button.setBounds(windowWidth + 75, 37, 32, 32);
296+
button.setBounds(windowWidth + 75, 37, TILE_SIZE, TILE_SIZE);
293297
button.addActionListener(_ -> content = TileType.WALL);
294298
this.add(button);
295299
}
@@ -299,7 +303,7 @@ private void createTargetButton() {
299303
button.setName(Component.TARGET_BUTTON.name());
300304
button.setOpaque(false);
301305
button.setContentAreaFilled(false);
302-
button.setBounds(windowWidth + 75, 74, 32, 32);
306+
button.setBounds(windowWidth + 75, 74, TILE_SIZE, TILE_SIZE);
303307
button.addActionListener(_ -> content = TileType.STORAGE_AREA);
304308
this.add(button);
305309
}
@@ -309,7 +313,7 @@ private void createEmptyButton() {
309313
button.setName(Component.EMPTY_BUTTON.name());
310314
button.setOpaque(false);
311315
button.setContentAreaFilled(false);
312-
button.setBounds(windowWidth + 75, 111, 32, 32);
316+
button.setBounds(windowWidth + 75, 111, TILE_SIZE, TILE_SIZE);
313317
button.addActionListener(_ -> content = TileType.FLOOR);
314318
this.add(button);
315319
}
@@ -332,16 +336,19 @@ public void mouseClicked(MouseEvent e) {}
332336
@Override
333337
public void mousePressed(MouseEvent e) {
334338
if (e.getX() < windowWidth + 31 && e.getY() < windowHeight + 31) {
335-
int l = Math.max((e.getX() - 10) / 32, 0);
336-
int c = Math.max((e.getY() - 32) / 32, 0);
339+
int l = Math.max((e.getX() - X_OFFSET) / TILE_SIZE, 0);
340+
int c = Math.max((e.getY() - TILE_SIZE) / TILE_SIZE, 0);
337341
controller.warehouse.getCase(c, l).setContent(content);
338342
repaint();
339343
}
340344
}
341-
@Override
345+
346+
@Override
342347
public void mouseReleased(MouseEvent e) {}
343-
@Override
348+
349+
@Override
344350
public void mouseEntered(MouseEvent e) {}
345-
@Override
351+
352+
@Override
346353
public void mouseExited(MouseEvent e) {}
347354
}

src/main/java/logic/TileType.java

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,26 @@
11
package logic;
22

33
public enum TileType {
4-
FLOOR,
5-
WALL,
6-
UNSTORED_BOX,
7-
STORED_BOX,
8-
STORAGE_AREA,
9-
WORKER_ON_FLOOR,
10-
WORKER_IN_STORAGE_AREA,
11-
OUTSIDE
4+
FLOOR('#'),
5+
WALL('M'),
6+
UNSTORED_BOX('C'),
7+
STORED_BOX('V'),
8+
STORAGE_AREA('T'),
9+
WORKER_ON_FLOOR('G'),
10+
WORKER_IN_STORAGE_AREA('B'),
11+
OUTSIDE('_');
12+
13+
private final char code;
14+
15+
TileType(char code) {
16+
this.code = code;
17+
}
18+
19+
/**
20+
* Returns the character code used to represent this tile type in level files.
21+
* @return the character code for this tile type
22+
*/
23+
public char getCode() {
24+
return code;
25+
}
1226
}

src/test/java/ihm/EditorTest.java

Lines changed: 90 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@
88

99
import javax.swing.*;
1010
import java.awt.*;
11+
import java.awt.event.MouseEvent;
1112
import java.awt.event.MouseListener;
1213
import java.awt.event.MouseMotionListener;
1314
import java.io.IOException;
1415
import java.nio.file.Files;
1516
import java.nio.file.Path;
1617
import java.util.Arrays;
18+
import java.util.List;
1719

1820
import static java.nio.file.Files.deleteIfExists;
1921
import static org.assertj.core.api.BDDAssertions.then;
@@ -26,9 +28,12 @@ class EditorTest {
2628

2729
private static final String TEST_LEVEL_NAME = "testEditorLevel";
2830
private static final Path TEST_LEVEL_PATH = Path.of("levels", TEST_LEVEL_NAME + ".txt");
31+
2932
private static final int TEST_ROWS = 10;
3033
private static final int TEST_COLUMNS = 10;
31-
34+
35+
private static final int Y_OFFSET = Editor.TILE_SIZE; // Vertical offset for grid positioning
36+
3237
private Editor editor;
3338

3439
@BeforeEach
@@ -83,85 +88,147 @@ void editor_has_required_components() {
8388
void editor_has_correct_mouse_listeners() {
8489
MouseListener[] mouseListeners = editor.getMouseListeners();
8590
then(mouseListeners.length).isPositive();
86-
91+
8792
MouseMotionListener[] mouseMotionListeners = editor.getMouseMotionListeners();
8893
then(mouseMotionListeners.length).isPositive();
8994
}
90-
95+
9196
@Test
9297
void player_button_sets_content_to_worker_on_floor() {
9398
// Given
9499
JButton button = findComponentByNameAsType(editor, Editor.Component.PLAYER_BUTTON.name(), JButton.class);
95-
100+
96101
// When - Simulate button click
97102
button.doClick();
98-
103+
99104
then(editor.getContent()).isEqualTo(TileType.WORKER_ON_FLOOR);
100105
}
101106

107+
@Test
108+
void save_button_saves_valid_level() throws Exception {
109+
// Given
110+
// Set up a valid level with one player, one box, and one target
111+
JButton playerButton = findComponentByNameAsType(editor, Editor.Component.PLAYER_BUTTON.name(), JButton.class);
112+
JButton boxButton = findComponentByNameAsType(editor, Editor.Component.BOX_BUTTON.name(), JButton.class);
113+
JButton targetButton = findComponentByNameAsType(editor, Editor.Component.TARGET_BUTTON.name(), JButton.class);
114+
JButton saveButton = findComponentByNameAsType(editor, Editor.Component.SAVE_BUTTON.name(), JButton.class);
115+
116+
// Add elements at their expected positions
117+
playerButton.doClick();
118+
var player = new ExpectedAt(1, 1);
119+
editor.mousePressed(mouseEventAt(
120+
Editor.X_OFFSET + player.x * Editor.TILE_SIZE,
121+
Y_OFFSET + player.y * Editor.TILE_SIZE
122+
));
123+
124+
boxButton.doClick();
125+
var box = new ExpectedAt(2, 2);
126+
editor.mousePressed(mouseEventAt(
127+
Editor.X_OFFSET + box.x * Editor.TILE_SIZE,
128+
Y_OFFSET + box.y * Editor.TILE_SIZE
129+
));
130+
131+
targetButton.doClick();
132+
var target = new ExpectedAt(3, 3);
133+
editor.mousePressed(mouseEventAt(
134+
Editor.X_OFFSET + target.x * Editor.TILE_SIZE,
135+
Y_OFFSET + target.y * Editor.TILE_SIZE
136+
));
137+
138+
// When
139+
saveButton.doClick();
140+
141+
// Then - Verify the file was created and contains valid content
142+
then(TEST_LEVEL_PATH).exists();
143+
List<String> lines = Files.readAllLines(TEST_LEVEL_PATH);
144+
145+
then(lines).hasSize(TEST_ROWS);
146+
then(lines).allSatisfy(line ->
147+
then(line.length()).isEqualTo(TEST_COLUMNS)
148+
);
149+
150+
// Verify the level contains the expected characters (converted from tile types)
151+
then(lines.get(player.y).charAt(player.x)) .isEqualTo(TileType.WORKER_ON_FLOOR.getCode());
152+
then(lines.get(box.y).charAt(box.x)) .isEqualTo(TileType.UNSTORED_BOX.getCode());
153+
then(lines.get(target.y).charAt(target.x)) .isEqualTo(TileType.STORAGE_AREA.getCode());
154+
}
155+
156+
private MouseEvent mouseEventAt(int x, int y) {
157+
return new MouseEvent(
158+
editor, // Component source
159+
MouseEvent.MOUSE_PRESSED, // Event type
160+
System.currentTimeMillis(), // When
161+
0, // No modifiers
162+
x, // x-coordinate
163+
y, // y-coordinate
164+
1, // Click count
165+
false // Popup trigger
166+
);
167+
}
168+
102169
@Test
103170
void background_button_sets_content_to_outside() {
104171
// Given
105172
JButton button = findComponentByNameAsType(editor, Editor.Component.BACKGROUND_BUTTON.name(), JButton.class);
106-
173+
107174
// When - Simulate button click
108175
button.doClick();
109-
176+
110177
then(editor.getContent()).isEqualTo(TileType.OUTSIDE);
111178
}
112179

113180
@Test
114181
void box_button_sets_content_to_unstored_box() {
115182
// Given
116183
JButton button = findComponentByNameAsType(editor, Editor.Component.BOX_BUTTON.name(), JButton.class);
117-
184+
118185
// When - Simulate button click
119186
button.doClick();
120-
187+
121188
then(editor.getContent()).isEqualTo(TileType.UNSTORED_BOX);
122189
}
123190

124191
@Test
125192
void box_on_target_button_sets_content_to_stored_box() {
126193
// Given
127194
JButton button = findComponentByNameAsType(editor, Editor.Component.BOX_ON_TARGET_BUTTON.name(), JButton.class);
128-
195+
129196
// When - Simulate button click
130197
button.doClick();
131-
198+
132199
then(editor.getContent()).isEqualTo(TileType.STORED_BOX);
133200
}
134201

135202
@Test
136203
void player_on_target_button_sets_content_to_worker_in_storage_area() {
137204
// Given
138205
JButton button = findComponentByNameAsType(editor, Editor.Component.PLAYER_ON_TARGET_BUTTON.name(), JButton.class);
139-
206+
140207
// When - Simulate button click
141208
button.doClick();
142-
209+
143210
then(editor.getContent()).isEqualTo(TileType.WORKER_IN_STORAGE_AREA);
144211
}
145212

146213
@Test
147214
void wall_button_sets_content_to_wall() {
148215
// Given
149216
JButton button = findComponentByNameAsType(editor, Editor.Component.WALL_BUTTON.name(), JButton.class);
150-
217+
151218
// When - Simulate button click
152219
button.doClick();
153-
220+
154221
then(editor.getContent()).isEqualTo(TileType.WALL);
155222
}
156223

157224
@Test
158225
void target_button_sets_content_to_storage_area() {
159226
// Given
160227
JButton button = findComponentByNameAsType(editor, Editor.Component.TARGET_BUTTON.name(), JButton.class);
161-
228+
162229
// When - Simulate button click
163230
button.doClick();
164-
231+
165232
then(editor.getContent()).isEqualTo(TileType.STORAGE_AREA);
166233
}
167234

@@ -241,4 +308,10 @@ ExitHandler defaultExitHandler() {
241308
then(Files.exists(TEST_LEVEL_PATH)).isFalse();
242309
verify(mockExitHandler).exit(ExitHandler.SUCCESS);
243310
}
311+
312+
/**
313+
* Represents expected positions in the test grid.
314+
*/
315+
private record ExpectedAt(int x, int y) {
316+
}
244317
}

0 commit comments

Comments
 (0)