From 8e04cdabf4e9fd683b49b07a0bb8fb244c8075b2 Mon Sep 17 00:00:00 2001 From: Mike Date: Mon, 19 Jan 2026 18:12:49 +0300 Subject: [PATCH 1/3] Test PR --- expressions/src/test/java/hse/java/BaseTest.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/expressions/src/test/java/hse/java/BaseTest.java b/expressions/src/test/java/hse/java/BaseTest.java index d00d95dc..8a7eda43 100644 --- a/expressions/src/test/java/hse/java/BaseTest.java +++ b/expressions/src/test/java/hse/java/BaseTest.java @@ -1,9 +1,14 @@ package hse.java; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; + public class BaseTest { @Test - void test() {} + void test() { + int actually = 1; + Assertions.assertEquals(1, actually); + } } From 40fd14d610649e96a3ef67d50c4077bcd31018ca Mon Sep 17 00:00:00 2001 From: Mike Date: Mon, 19 Jan 2026 18:16:24 +0300 Subject: [PATCH 2/3] Initial commit --- .github/workflows/pr-tests.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/pr-tests.yml b/.github/workflows/pr-tests.yml index 8996e610..0610daac 100644 --- a/.github/workflows/pr-tests.yml +++ b/.github/workflows/pr-tests.yml @@ -37,13 +37,9 @@ jobs: - name: Copy test files run: | - echo "📂 Listing source directory:" - ls -R hidden-tests - echo "🚀 Copying tests..." cp -r hidden-tests/expressions/src/test/java/hse/java/* main-repo/expressions/src/test/java/hse/java/ echo "✅ Tests copied" - rm -rf hidden-tests - name: Run Maven tests From c2dbe288cedae0c64d6cc7f2ba7b473ce75cbd37 Mon Sep 17 00:00:00 2001 From: Mike Date: Tue, 27 Jan 2026 12:08:01 +0300 Subject: [PATCH 3/3] Tests --- .github/workflows/pr-tests.yml | 59 ++---------------- .gitignore | 5 +- .../java/hse/java/lectures/lecture1/Cat.java | 17 ----- expressions/icon.icns => icon.icns | Bin expressions/make-app.sh => make-app.sh | 0 ...cns-from-icon.sh => make-icns-from-icon.sh | 0 expressions/pom.xml => pom.xml | 14 +++-- .../main/java/hse/java/IntExpression.java | 0 .../src => src}/main/java/hse/java/Main.java | 0 .../main/java/hse/java/impl/Hello.java | 0 .../java/hse/java/lectures/lecture1/Game.java | 15 +++-- .../java/lectures/lecture1/HelloWorld.java | 7 +++ .../java/hse/java/practice/task1/Cube.java | 22 +++++++ .../hse/java/practice/task1/CubeColor.java | 10 +++ .../java/hse/java/practice/task1/Edge.java | 36 +++++++++++ .../hse/java/practice/task1/EdgePosition.java | 18 ++++++ .../java/practice/task1/RotateDirection.java | 11 ++++ .../hse/java/practice/task1/RubiksCube.java | 42 +++++++++++++ src/main/java/hse/java/practice/task1/task.md | 16 +++++ .../src => src}/main/java/hse/java/task.md | 0 .../src => src}/main/resources/icon.png | Bin .../test/java/hse/java/BaseTest.java | 5 +- .../java/practice/task1/CubeSimpleTest.java | 57 +++++++++++++++++ .../practice/task1/frontClockwieseState.json | 32 ++++++++++ 24 files changed, 282 insertions(+), 84 deletions(-) delete mode 100644 expressions/src/main/java/hse/java/lectures/lecture1/Cat.java rename expressions/icon.icns => icon.icns (100%) rename expressions/make-app.sh => make-app.sh (100%) rename expressions/make-icns-from-icon.sh => make-icns-from-icon.sh (100%) rename expressions/pom.xml => pom.xml (85%) rename {expressions/src => src}/main/java/hse/java/IntExpression.java (100%) rename {expressions/src => src}/main/java/hse/java/Main.java (100%) rename {expressions/src => src}/main/java/hse/java/impl/Hello.java (100%) rename expressions/src/main/java/hse/java/lectures/lecture1/HelloWorld.java => src/main/java/hse/java/lectures/lecture1/Game.java (53%) create mode 100644 src/main/java/hse/java/lectures/lecture1/HelloWorld.java create mode 100644 src/main/java/hse/java/practice/task1/Cube.java create mode 100644 src/main/java/hse/java/practice/task1/CubeColor.java create mode 100644 src/main/java/hse/java/practice/task1/Edge.java create mode 100644 src/main/java/hse/java/practice/task1/EdgePosition.java create mode 100644 src/main/java/hse/java/practice/task1/RotateDirection.java create mode 100644 src/main/java/hse/java/practice/task1/RubiksCube.java create mode 100644 src/main/java/hse/java/practice/task1/task.md rename {expressions/src => src}/main/java/hse/java/task.md (100%) rename {expressions/src => src}/main/resources/icon.png (100%) rename {expressions/src => src}/test/java/hse/java/BaseTest.java (50%) create mode 100644 src/test/java/hse/java/practice/task1/CubeSimpleTest.java create mode 100644 src/test/resources/hse/java/practice/task1/frontClockwieseState.json diff --git a/.github/workflows/pr-tests.yml b/.github/workflows/pr-tests.yml index 0610daac..68b9c268 100644 --- a/.github/workflows/pr-tests.yml +++ b/.github/workflows/pr-tests.yml @@ -16,9 +16,6 @@ jobs: steps: - name: Checkout main repository (PR) uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha }} - path: main-repo - name: Set up JDK 17 uses: actions/setup-java@v4 @@ -33,59 +30,13 @@ jobs: repository: ${{ secrets.TESTS_REPO_OWNER }}/${{ secrets.TESTS_REPO_NAME }} token: ${{ secrets.TESTS_REPO_TOKEN }} path: hidden-tests - fetch-depth: 1 - name: Copy test files run: | - echo "🚀 Copying tests..." - cp -r hidden-tests/expressions/src/test/java/hse/java/* main-repo/expressions/src/test/java/hse/java/ - echo "✅ Tests copied" + echo "Copying test data" + cp -r hidden-tests/src/test/java/* main-repo/src/test/java/ + echo "Test data copied" rm -rf hidden-tests - - name: Run Maven tests - id: test - working-directory: main-repo/expressions - run: mvn clean test - continue-on-error: true - - - name: Comment PR with test results - if: always() - uses: actions/github-script@v7 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const testStatus = '${{ steps.test.outcome }}'; - let comment = '## 🧪 Результаты автоматического тестирования\n\n'; - - if (testStatus === 'success') { - comment += '✅ **Все тесты прошли успешно!**\n\n'; - } else { - comment += '❌ **Некоторые тесты не прошли.**\n\n'; - } - - const comments = await github.rest.issues.listComments({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - }); - - const botComment = comments.data.find(comment => - comment.user.type === 'Bot' && - comment.body.includes('Результаты автоматического тестирования') - ); - - if (botComment) { - await github.rest.issues.updateComment({ - owner: context.repo.owner, - repo: context.repo.repo, - comment_id: botComment.id, - body: comment - }); - } else { - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - body: comment - }); - } + - name: Run tests + run: mvn -B test diff --git a/.gitignore b/.gitignore index 7e96e2ba..758355d6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,12 @@ .idea .DS_Store +.mvn *.class +target/* expressions/.vscode expressions/app/* -expressions/target/* +target/* presentations/* +out/* diff --git a/expressions/src/main/java/hse/java/lectures/lecture1/Cat.java b/expressions/src/main/java/hse/java/lectures/lecture1/Cat.java deleted file mode 100644 index cf976e10..00000000 --- a/expressions/src/main/java/hse/java/lectures/lecture1/Cat.java +++ /dev/null @@ -1,17 +0,0 @@ -package hse.java.lectures.lecture1; - -public class Cat { - - private String name; - - public void calculate() { - int x = 2; - int y = 3; - int z = x + y; - } - - public void meow() { - System.out.println(name + ": MEOW"); - } - -} diff --git a/expressions/icon.icns b/icon.icns similarity index 100% rename from expressions/icon.icns rename to icon.icns diff --git a/expressions/make-app.sh b/make-app.sh similarity index 100% rename from expressions/make-app.sh rename to make-app.sh diff --git a/expressions/make-icns-from-icon.sh b/make-icns-from-icon.sh similarity index 100% rename from expressions/make-icns-from-icon.sh rename to make-icns-from-icon.sh diff --git a/expressions/pom.xml b/pom.xml similarity index 85% rename from expressions/pom.xml rename to pom.xml index 0aeef416..ade43fe2 100644 --- a/expressions/pom.xml +++ b/pom.xml @@ -5,8 +5,8 @@ 4.0.0 hse.java - expressions - 1.0-SNAPSHOT + hse-java + 1 17 @@ -24,6 +24,13 @@ ${junit.version} test + + + com.fasterxml.jackson.core + jackson-databind + 2.17.2 + test + @@ -45,7 +52,7 @@ true - hse.java.lectures.lecture1.HelloWorld + hse.java.lectures.lecture1.Game @@ -55,7 +62,6 @@ maven-surefire-plugin ${maven.surefire.version} - diff --git a/expressions/src/main/java/hse/java/IntExpression.java b/src/main/java/hse/java/IntExpression.java similarity index 100% rename from expressions/src/main/java/hse/java/IntExpression.java rename to src/main/java/hse/java/IntExpression.java diff --git a/expressions/src/main/java/hse/java/Main.java b/src/main/java/hse/java/Main.java similarity index 100% rename from expressions/src/main/java/hse/java/Main.java rename to src/main/java/hse/java/Main.java diff --git a/expressions/src/main/java/hse/java/impl/Hello.java b/src/main/java/hse/java/impl/Hello.java similarity index 100% rename from expressions/src/main/java/hse/java/impl/Hello.java rename to src/main/java/hse/java/impl/Hello.java diff --git a/expressions/src/main/java/hse/java/lectures/lecture1/HelloWorld.java b/src/main/java/hse/java/lectures/lecture1/Game.java similarity index 53% rename from expressions/src/main/java/hse/java/lectures/lecture1/HelloWorld.java rename to src/main/java/hse/java/lectures/lecture1/Game.java index a147ed3c..bf85f916 100644 --- a/expressions/src/main/java/hse/java/lectures/lecture1/HelloWorld.java +++ b/src/main/java/hse/java/lectures/lecture1/Game.java @@ -3,19 +3,26 @@ import javax.swing.*; import java.awt.*; -public class HelloWorld { +public class Game { public static void main(String[] args) { + JFrame frame = new JFrame("XO"); - JFrame frame = new JFrame("Oh my God!!!"); frame.setSize(300, 300); + frame.setLocation(200, 200); + + JButton[][] buttons = new JButton[3][3]; JPanel panel = new JPanel(new GridLayout(3,3)); for (int i = 0; i < 9; i++) { - panel.add(new JButton()); + JButton button = new JButton(); + button.addActionListener(a -> { + button.setText("X"); + }); + panel.add(button); } frame.add(panel); + JDialog dialog; frame.setVisible(true); - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } } diff --git a/src/main/java/hse/java/lectures/lecture1/HelloWorld.java b/src/main/java/hse/java/lectures/lecture1/HelloWorld.java new file mode 100644 index 00000000..21025a34 --- /dev/null +++ b/src/main/java/hse/java/lectures/lecture1/HelloWorld.java @@ -0,0 +1,7 @@ +package hse.java.lectures.lecture1; + +public class HelloWorld { + public static void main(String[] args) { + System.out.println("Hello world"); + } +} diff --git a/src/main/java/hse/java/practice/task1/Cube.java b/src/main/java/hse/java/practice/task1/Cube.java new file mode 100644 index 00000000..0460a67c --- /dev/null +++ b/src/main/java/hse/java/practice/task1/Cube.java @@ -0,0 +1,22 @@ +package hse.java.practice.task1; + +public interface Cube { + + // Метод вращения верхней грани кубика + void up(RotateDirection direction); + + // Метод вращения нижней грани кубика + void down(RotateDirection direction); + + // Метод вращения левой грани кубика + void left(RotateDirection direction); + + // Метод вращения правой грани кубика + void right(RotateDirection direction); + + // Метод вращения передней грани кубика + void front(RotateDirection direction); + + // Метод вращения задней грани кубика + void back(RotateDirection direction); +} diff --git a/src/main/java/hse/java/practice/task1/CubeColor.java b/src/main/java/hse/java/practice/task1/CubeColor.java new file mode 100644 index 00000000..694eda76 --- /dev/null +++ b/src/main/java/hse/java/practice/task1/CubeColor.java @@ -0,0 +1,10 @@ +package hse.java.practice.task1; + +public enum CubeColor { + GREEN, + RED, + BLUE, + WHITE, + YELLOW, + ORANGE +} diff --git a/src/main/java/hse/java/practice/task1/Edge.java b/src/main/java/hse/java/practice/task1/Edge.java new file mode 100644 index 00000000..0b140e6b --- /dev/null +++ b/src/main/java/hse/java/practice/task1/Edge.java @@ -0,0 +1,36 @@ +package hse.java.practice.task1; + +import java.awt.*; +import java.util.Arrays; +import java.util.Random; + +public class Edge { + + private final CubeColor[][] parts; + + public Edge(CubeColor[][] parts) { + this.parts = parts; + } + + public Edge(CubeColor color) { + this.parts = new CubeColor[3][3]; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + parts[i][j] = color; + } + } + } + + public Edge() { + parts = new CubeColor[3][3]; + } + + public CubeColor[][] getParts() { + return parts; + } + + @Override + public String toString() { + return Arrays.deepToString(parts); + } +} diff --git a/src/main/java/hse/java/practice/task1/EdgePosition.java b/src/main/java/hse/java/practice/task1/EdgePosition.java new file mode 100644 index 00000000..f96cdf3c --- /dev/null +++ b/src/main/java/hse/java/practice/task1/EdgePosition.java @@ -0,0 +1,18 @@ +package hse.java.practice.task1; + +/** + * Ордер в енуме соответствует позиции грани куба + * в массиве граней + * edges[0] -> UP + * edges[1] -> DOWN + * edges[2] -> LEFT + * ... + */ +public enum EdgePosition { + UP, + DOWN, + LEFT, + RIGHT, + FRONT, + BACK +} diff --git a/src/main/java/hse/java/practice/task1/RotateDirection.java b/src/main/java/hse/java/practice/task1/RotateDirection.java new file mode 100644 index 00000000..72263ec0 --- /dev/null +++ b/src/main/java/hse/java/practice/task1/RotateDirection.java @@ -0,0 +1,11 @@ +package hse.java.practice.task1; + +/** + * Направление вращения грани кубика рубика + */ +public enum RotateDirection { + // Против часовой стрелки + COUNTERCLOCKWISE, + // По часовой стрелке + CLOCKWISE +} diff --git a/src/main/java/hse/java/practice/task1/RubiksCube.java b/src/main/java/hse/java/practice/task1/RubiksCube.java new file mode 100644 index 00000000..3f605191 --- /dev/null +++ b/src/main/java/hse/java/practice/task1/RubiksCube.java @@ -0,0 +1,42 @@ +package hse.java.practice.task1; + + +import java.util.Arrays; + +/** + * Необходимо реализовать интерфейс Cube + * При повороте передней грани, меняются верх низ право и лево + */ +public class RubiksCube { + + private static final int EDGES_COUNT = 6; + + private final Edge[] edges = new Edge[EDGES_COUNT]; + + /** + * Создать валидный собранный кубик + * грани разместить по ордеру в енуме цветов + * грань 0 -> цвет 0 + * грань 1 -> цвет 1 + * ... + */ + public RubiksCube() { + CubeColor[] colors = CubeColor.values(); + for (int i = 0; i < 6; i++) { + edges[i] = new Edge(colors[i]); + } + } + + public void front(RotateDirection direction) { + + } + + public Edge[] getEdges() { + return edges; + } + + @Override + public String toString() { + return Arrays.toString(edges); + } +} diff --git a/src/main/java/hse/java/practice/task1/task.md b/src/main/java/hse/java/practice/task1/task.md new file mode 100644 index 00000000..e3883190 --- /dev/null +++ b/src/main/java/hse/java/practice/task1/task.md @@ -0,0 +1,16 @@ +Необходимо реализовать методы поворота кубика Рубика. + +Кубик представляет собой классический куб 3×3×3: +- 6 граней; +- каждая грань состоит из 9 элементов (стикеров); +- каждый элемент однозначно определяется своим цветом. + +Каждую из граней можно вращать по часовой стрелке или против часовой стрелки. +При выполнении поворота: +- изменяется расположение элементов на самой вращаемой грани; +- переставляются элементы на четырёх соседних гранях, примыкающих к этой грани. + +В рамках задачи необходимо: +- формально представить состояние кубика (структуры `Cube`, `Edge`, `CubeColor`, `EdgePosition` уже заданы или должны быть использованы согласно условию); +- реализовать операции поворота граней во всех допустимых направлениях согласно перечислению `RotateDirection`; +- гарантировать корректное изменение состояния кубика при каждом повороте, чтобы последовательность поворотов давала ожидаемый результат (см. тесты в `CubeSimpleTest`). \ No newline at end of file diff --git a/expressions/src/main/java/hse/java/task.md b/src/main/java/hse/java/task.md similarity index 100% rename from expressions/src/main/java/hse/java/task.md rename to src/main/java/hse/java/task.md diff --git a/expressions/src/main/resources/icon.png b/src/main/resources/icon.png similarity index 100% rename from expressions/src/main/resources/icon.png rename to src/main/resources/icon.png diff --git a/expressions/src/test/java/hse/java/BaseTest.java b/src/test/java/hse/java/BaseTest.java similarity index 50% rename from expressions/src/test/java/hse/java/BaseTest.java rename to src/test/java/hse/java/BaseTest.java index 8a7eda43..45385341 100644 --- a/expressions/src/test/java/hse/java/BaseTest.java +++ b/src/test/java/hse/java/BaseTest.java @@ -1,14 +1,11 @@ package hse.java; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; - public class BaseTest { @Test void test() { - int actually = 1; - Assertions.assertEquals(1, actually); + } } diff --git a/src/test/java/hse/java/practice/task1/CubeSimpleTest.java b/src/test/java/hse/java/practice/task1/CubeSimpleTest.java new file mode 100644 index 00000000..22547e89 --- /dev/null +++ b/src/test/java/hse/java/practice/task1/CubeSimpleTest.java @@ -0,0 +1,57 @@ +package hse.java.practice.task1; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +public class CubeSimpleTest { + + private static final ObjectMapper MAPPER = new ObjectMapper(); + + @Test + void printTest() { + RubiksCube cube = new RubiksCube(); + CubeColor[] colors = CubeColor.values(); + for (int i = 0; i < 6; i++) { + Edge edge = cube.getEdges()[i]; + CubeColor[][] edgeColors = edge.getParts(); + for (CubeColor[] row : edgeColors) { + for (CubeColor color : row) { + Assertions.assertEquals(color, colors[i]); + } + } + } + } + + @Test + void frontClockwise() { + RubiksCube cube = new RubiksCube(); + cube.front(RotateDirection.CLOCKWISE); + + CubeColor[][][] state = readStateFromFile("frontClockwieseState.json"); + + CubeColor[][][] actuallyState = Arrays.stream(cube.getEdges()) + .map(Edge::getParts) + .toArray(CubeColor[][][]::new); + + Assertions.assertArrayEquals(state, actuallyState); + } + + private CubeColor[][][] readStateFromFile(String fileName) { + String resourcePath = "hse/java/practice/task1/" + fileName; + try (InputStream is = CubeSimpleTest.class.getClassLoader().getResourceAsStream(resourcePath)) { + if (is == null) { + throw new IllegalArgumentException("Resource not found: " + resourcePath); + } + String json = new String(is.readAllBytes(), StandardCharsets.UTF_8); + return MAPPER.readValue(json, CubeColor[][][].class); + } catch (IOException e) { + throw new RuntimeException("Failed to read/parse state file: " + fileName, e); + } + } +} diff --git a/src/test/resources/hse/java/practice/task1/frontClockwieseState.json b/src/test/resources/hse/java/practice/task1/frontClockwieseState.json new file mode 100644 index 00000000..44471923 --- /dev/null +++ b/src/test/resources/hse/java/practice/task1/frontClockwieseState.json @@ -0,0 +1,32 @@ +[ + [ + ["GREEN", "GREEN", "GREEN"], + ["GREEN", "GREEN", "GREEN"], + ["BLUE", "BLUE", "BLUE"] + ], + [ + ["WHITE", "WHITE", "WHITE"], + ["RED", "RED", "RED"], + ["RED", "RED", "RED"] + ], + [ + ["BLUE", "BLUE", "RED"], + ["BLUE", "BLUE", "RED"], + ["BLUE", "BLUE", "RED"] + ], + [ + ["GREEN", "WHITE", "WHITE"], + ["GREEN", "WHITE", "WHITE"], + ["GREEN", "WHITE", "WHITE"] + ], + [ + ["YELLOW", "YELLOW", "YELLOW"], + ["YELLOW", "YELLOW", "YELLOW"], + ["YELLOW", "YELLOW", "YELLOW"] + ], + [ + ["ORANGE", "ORANGE", "ORANGE"], + ["ORANGE", "ORANGE", "ORANGE"], + ["ORANGE", "ORANGE", "ORANGE"] + ] +]