diff --git a/discussion/index.ndjson b/discussion/index.ndjson index ee59b7d3..1945b847 100644 --- a/discussion/index.ndjson +++ b/discussion/index.ndjson @@ -10,4 +10,4 @@ {"type":"discussion","id":"DSC-0009","status":"open","ticket":"studio-debugger-workspace-integration","title":"Integrate ../debugger into Studio as a dedicated workspace","created_at":"2026-03-30","updated_at":"2026-03-30","tags":["studio","debugger","workspace","integration","shell"],"agendas":[{"id":"AGD-0009","file":"AGD-0009-studio-debugger-workspace-integration.md","status":"open","created_at":"2026-03-30","updated_at":"2026-03-30"}],"decisions":[],"plans":[],"lessons":[]} {"type":"discussion","id":"DSC-0010","status":"done","ticket":"studio-code-editor-workspace-foundations","title":"Establish Code Editor workspace foundations in Studio without LSP","created_at":"2026-03-30","updated_at":"2026-03-31","tags":["studio","editor","workspace","multi-frontend","lsp-deferred"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0026","file":"discussion/lessons/DSC-0010-studio-code-editor-workspace-foundations/LSN-0026-read-only-editor-foundations-and-semantic-deferral.md","status":"done","created_at":"2026-03-31","updated_at":"2026-03-31"}]} {"type":"discussion","id":"DSC-0011","status":"done","ticket":"compiler-analyze-compile-build-pipeline-split","title":"Split compiler pipeline into analyze, compile, and build entrypoints","created_at":"2026-03-30","updated_at":"2026-03-30","tags":["compiler","pipeline","artifacts","build","analysis"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0025","file":"discussion/lessons/DSC-0011-compiler-analyze-compile-build-pipeline-split/LSN-0025-compiler-pipeline-entrypoints-and-result-boundaries.md","status":"done","created_at":"2026-03-30","updated_at":"2026-03-30"}]} -{"type":"discussion","id":"DSC-0012","status":"open","ticket":"studio-editor-document-vfs-boundary","title":"Definir um boundary de VFS documental para tree/view/open files no Code Editor do Studio","created_at":"2026-03-31","updated_at":"2026-03-31","tags":["studio","editor","workspace","vfs","filesystem","boundary"],"agendas":[{"id":"AGD-0012","file":"AGD-0012-studio-editor-document-vfs-boundary.md","status":"in_progress","created_at":"2026-03-31","updated_at":"2026-03-31"}],"decisions":[{"id":"DEC-0009","file":"DEC-0009-studio-prometeu-vfs-project-document-boundary.md","status":"in_progress","created_at":"2026-03-31","updated_at":"2026-03-31","ref_agenda":"AGD-0012"}],"plans":[{"id":"PLN-0015","file":"PLN-0015-propagate-dec-0009-into-studio-specs.md","status":"done","created_at":"2026-03-31","updated_at":"2026-03-31","ref_decisions":["DEC-0009"]},{"id":"PLN-0016","file":"PLN-0016-build-prometeu-vfs-filesystem-backed-core.md","status":"done","created_at":"2026-03-31","updated_at":"2026-03-31","ref_decisions":["DEC-0009"]},{"id":"PLN-0017","file":"PLN-0017-add-studio-project-session-ownership-for-prometeu-vfs.md","status":"done","created_at":"2026-03-31","updated_at":"2026-03-31","ref_decisions":["DEC-0009"]},{"id":"PLN-0018","file":"PLN-0018-migrate-code-editor-to-prometeu-vfs.md","status":"review","created_at":"2026-03-31","updated_at":"2026-03-31","ref_decisions":["DEC-0009"]}],"lessons":[]} +{"type":"discussion","id":"DSC-0012","status":"open","ticket":"studio-editor-document-vfs-boundary","title":"Definir um boundary de VFS documental para tree/view/open files no Code Editor do Studio","created_at":"2026-03-31","updated_at":"2026-03-31","tags":["studio","editor","workspace","vfs","filesystem","boundary"],"agendas":[{"id":"AGD-0012","file":"AGD-0012-studio-editor-document-vfs-boundary.md","status":"in_progress","created_at":"2026-03-31","updated_at":"2026-03-31"}],"decisions":[{"id":"DEC-0009","file":"DEC-0009-studio-prometeu-vfs-project-document-boundary.md","status":"in_progress","created_at":"2026-03-31","updated_at":"2026-03-31","ref_agenda":"AGD-0012"}],"plans":[{"id":"PLN-0015","file":"PLN-0015-propagate-dec-0009-into-studio-specs.md","status":"done","created_at":"2026-03-31","updated_at":"2026-03-31","ref_decisions":["DEC-0009"]},{"id":"PLN-0016","file":"PLN-0016-build-prometeu-vfs-filesystem-backed-core.md","status":"done","created_at":"2026-03-31","updated_at":"2026-03-31","ref_decisions":["DEC-0009"]},{"id":"PLN-0017","file":"PLN-0017-add-studio-project-session-ownership-for-prometeu-vfs.md","status":"done","created_at":"2026-03-31","updated_at":"2026-03-31","ref_decisions":["DEC-0009"]},{"id":"PLN-0018","file":"PLN-0018-migrate-code-editor-to-prometeu-vfs.md","status":"done","created_at":"2026-03-31","updated_at":"2026-03-31","ref_decisions":["DEC-0009"]}],"lessons":[]} diff --git a/discussion/workflow/plans/PLN-0018-migrate-code-editor-to-prometeu-vfs.md b/discussion/workflow/plans/PLN-0018-migrate-code-editor-to-prometeu-vfs.md index 1ca3989e..3774f82e 100644 --- a/discussion/workflow/plans/PLN-0018-migrate-code-editor-to-prometeu-vfs.md +++ b/discussion/workflow/plans/PLN-0018-migrate-code-editor-to-prometeu-vfs.md @@ -2,9 +2,9 @@ id: PLN-0018 ticket: studio-editor-document-vfs-boundary title: Migrate the Code Editor workspace to consume `prometeu-vfs` -status: review +status: done created: 2026-03-31 -completed: +completed: 2026-03-31 tags: - studio - editor diff --git a/prometeu-studio/src/main/java/p/studio/window/MainView.java b/prometeu-studio/src/main/java/p/studio/window/MainView.java index 342053a4..9a6d0a4e 100644 --- a/prometeu-studio/src/main/java/p/studio/window/MainView.java +++ b/prometeu-studio/src/main/java/p/studio/window/MainView.java @@ -28,7 +28,7 @@ public final class MainView extends BorderPane { setTop(new StudioShellTopBarControl(menuBar)); host.register(new AssetWorkspace(projectReference)); - host.register(new EditorWorkspace(projectReference)); + host.register(new EditorWorkspace(projectReference, projectSession.projectDocumentVfs())); // host.register(new PlaceholderWorkspace(WorkspaceId.DEBUG, I18n.WORKSPACE_DEBUG, "Debug")); host.register(new ShipperWorkspace(projectReference)); diff --git a/prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorFileBufferLoader.java b/prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorFileBufferLoader.java deleted file mode 100644 index e18ba690..00000000 --- a/prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorFileBufferLoader.java +++ /dev/null @@ -1,63 +0,0 @@ -package p.studio.workspaces.editor; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.ByteBuffer; -import java.nio.charset.CharacterCodingException; -import java.nio.charset.CodingErrorAction; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Objects; -import java.util.Optional; - -public final class EditorFileBufferLoader { - - public Optional load(final Path path) { - final var normalizedPath = Objects.requireNonNull(path, "path").toAbsolutePath().normalize(); - if (!Files.isRegularFile(normalizedPath)) { - return Optional.empty(); - } - - final byte[] bytes; - try { - bytes = Files.readAllBytes(normalizedPath); - } catch (IOException ioException) { - throw new UncheckedIOException(ioException); - } - - if (containsNulByte(bytes)) { - return Optional.empty(); - } - - final String content; - try { - content = StandardCharsets.UTF_8.newDecoder() - .onMalformedInput(CodingErrorAction.REPORT) - .onUnmappableCharacter(CodingErrorAction.REPORT) - .decode(ByteBuffer.wrap(bytes)) - .toString(); - } catch (CharacterCodingException codingException) { - return Optional.empty(); - } - - return Optional.of(new EditorOpenFileBuffer( - normalizedPath, - normalizedPath.getFileName().toString(), - content, - lineSeparator(content))); - } - - private boolean containsNulByte(final byte[] bytes) { - for (final byte value : bytes) { - if (value == 0) { - return true; - } - } - return false; - } - - private String lineSeparator(final String content) { - return content.contains("\r\n") ? "CRLF" : "LF"; - } -} diff --git a/prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorProjectNavigatorPanel.java b/prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorProjectNavigatorPanel.java index c45b4904..40807231 100644 --- a/prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorProjectNavigatorPanel.java +++ b/prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorProjectNavigatorPanel.java @@ -1,6 +1,7 @@ package p.studio.workspaces.editor; import javafx.geometry.Insets; +import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.Tooltip; @@ -12,9 +13,10 @@ import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; import javafx.scene.layout.Region; import javafx.scene.layout.StackPane; -import javafx.scene.Node; import p.studio.Container; import p.studio.utilities.i18n.I18n; +import p.studio.vfs.VfsProjectNode; +import p.studio.vfs.VfsProjectSnapshot; import java.nio.file.Path; import java.util.HashSet; @@ -26,12 +28,12 @@ import java.util.function.Consumer; public final class EditorProjectNavigatorPanel extends BorderPane { private final Button revealActiveButton = new Button(); private final Button refreshButton = new Button(); - private final TreeView treeView = new TreeView<>(); + private final TreeView treeView = new TreeView<>(); private final Label emptyState = emptyLabel(); private final StackPane content = new StackPane(); private Runnable revealActiveFileAction = () -> { }; private Runnable refreshAction = () -> { }; - private Consumer fileSelectionAction = node -> { }; + private Consumer fileSelectionAction = node -> { }; public EditorProjectNavigatorPanel() { getStyleClass().addAll("editor-workspace-panel", "editor-workspace-navigator-panel"); @@ -82,7 +84,7 @@ public final class EditorProjectNavigatorPanel extends BorderPane { treeView.setFocusTraversable(false); treeView.setCellFactory(ignored -> new TreeCell<>() { @Override - protected void updateItem(final EditorProjectNode item, final boolean empty) { + protected void updateItem(final VfsProjectNode item, final boolean empty) { super.updateItem(item, empty); getStyleClass().remove("editor-workspace-tree-cell-tagged"); getStyleClass().remove("editor-workspace-tree-cell-root"); @@ -121,11 +123,11 @@ public final class EditorProjectNavigatorPanel extends BorderPane { revealActiveButton.setDisable(!available); } - public void setFileSelectionAction(final Consumer fileSelectionAction) { + public void setFileSelectionAction(final Consumer fileSelectionAction) { this.fileSelectionAction = Objects.requireNonNull(fileSelectionAction, "fileSelectionAction"); } - public void setSnapshot(final EditorProjectSnapshot snapshot) { + public void setSnapshot(final VfsProjectSnapshot snapshot) { final var currentSelection = selectedPath(); final var expandedPaths = captureExpandedPaths(treeView.getRoot()); final var rootItem = buildTreeItem(Objects.requireNonNull(snapshot, "snapshot").rootNode(), expandedPaths, true); @@ -147,11 +149,11 @@ public final class EditorProjectNavigatorPanel extends BorderPane { }); } - private TreeItem buildTreeItem( - final EditorProjectNode node, + private TreeItem buildTreeItem( + final VfsProjectNode node, final Set expandedPaths, final boolean isRoot) { - final TreeItem item = node.directory() + final TreeItem item = node.directory() ? new DirectoryTreeItem(node) : new TreeItem<>(node); item.setExpanded(isRoot || expandedPaths.contains(node.path())); @@ -161,7 +163,7 @@ public final class EditorProjectNavigatorPanel extends BorderPane { return item; } - private Set captureExpandedPaths(final TreeItem item) { + private Set captureExpandedPaths(final TreeItem item) { final var expandedPaths = new HashSet(); if (item == null) { return expandedPaths; @@ -170,7 +172,7 @@ public final class EditorProjectNavigatorPanel extends BorderPane { return expandedPaths; } - private void collectExpandedPaths(final TreeItem item, final Set expandedPaths) { + private void collectExpandedPaths(final TreeItem item, final Set expandedPaths) { final var value = item.getValue(); if (value != null && item.isExpanded()) { expandedPaths.add(value.path()); @@ -181,10 +183,10 @@ public final class EditorProjectNavigatorPanel extends BorderPane { private Optional selectedPath() { return Optional.ofNullable(treeView.getSelectionModel().getSelectedItem()) .map(TreeItem::getValue) - .map(EditorProjectNode::path); + .map(VfsProjectNode::path); } - private void restoreSelection(final TreeItem rootItem, final Optional selectedPath) { + private void restoreSelection(final TreeItem rootItem, final Optional selectedPath) { treeView.getSelectionModel().clearSelection(); if (selectedPath.isEmpty()) { return; @@ -193,7 +195,7 @@ public final class EditorProjectNavigatorPanel extends BorderPane { .ifPresent(item -> treeView.getSelectionModel().select(item)); } - private Optional> findTreeItem(final TreeItem item, final Path path) { + private Optional> findTreeItem(final TreeItem item, final Path path) { if (item == null || item.getValue() == null) { return Optional.empty(); } @@ -216,15 +218,15 @@ public final class EditorProjectNavigatorPanel extends BorderPane { emptyState.setManaged(empty); } - private void expandAncestors(final TreeItem item) { - TreeItem current = item; + private void expandAncestors(final TreeItem item) { + TreeItem current = item; while (current != null) { current.setExpanded(true); current = current.getParent(); } } - private Node iconFor(final EditorProjectNode node, final TreeItem treeItem) { + private Node iconFor(final VfsProjectNode node, final TreeItem treeItem) { if (node.directory()) { if (isBuildTone(node)) { return EditorWorkspaceIcons.folderBuild(); @@ -241,7 +243,7 @@ public final class EditorProjectNavigatorPanel extends BorderPane { return EditorWorkspaceIcons.file(); } - private String labelFor(final EditorProjectNode node, final TreeItem treeItem) { + private String labelFor(final VfsProjectNode node, final TreeItem treeItem) { if (!isRoot(treeItem)) { return node.displayName(); } @@ -252,7 +254,7 @@ public final class EditorProjectNavigatorPanel extends BorderPane { return directoryName + " (" + node.displayName() + ")"; } - private boolean isInsideTaggedSourceRoot(final TreeItem item) { + private boolean isInsideTaggedSourceRoot(final TreeItem item) { var current = item == null ? null : item.getParent(); while (current != null && current.getValue() != null) { if (current.getValue().taggedSourceRoot()) { @@ -263,11 +265,11 @@ public final class EditorProjectNavigatorPanel extends BorderPane { return false; } - private boolean isRoot(final TreeItem item) { + private boolean isRoot(final TreeItem item) { return item != null && item.getParent() == null; } - private boolean isBuildTone(final EditorProjectNode node) { + private boolean isBuildTone(final VfsProjectNode node) { return node.directory() && ("build".equals(node.displayName()) || "cartridge".equals(node.displayName())); } @@ -280,8 +282,8 @@ public final class EditorProjectNavigatorPanel extends BorderPane { return placeholder; } - private static final class DirectoryTreeItem extends TreeItem { - private DirectoryTreeItem(final EditorProjectNode node) { + private static final class DirectoryTreeItem extends TreeItem { + private DirectoryTreeItem(final VfsProjectNode node) { super(node); } diff --git a/prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorProjectNode.java b/prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorProjectNode.java deleted file mode 100644 index fcee2a0f..00000000 --- a/prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorProjectNode.java +++ /dev/null @@ -1,18 +0,0 @@ -package p.studio.workspaces.editor; - -import java.nio.file.Path; -import java.util.List; -import java.util.Objects; - -public record EditorProjectNode( - Path path, - String displayName, - boolean directory, - boolean taggedSourceRoot, - List children) { - public EditorProjectNode { - path = Objects.requireNonNull(path, "path").toAbsolutePath().normalize(); - displayName = Objects.requireNonNull(displayName, "displayName"); - children = List.copyOf(children); - } -} diff --git a/prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorProjectSnapshot.java b/prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorProjectSnapshot.java deleted file mode 100644 index c7f9a06a..00000000 --- a/prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorProjectSnapshot.java +++ /dev/null @@ -1,13 +0,0 @@ -package p.studio.workspaces.editor; - -import java.nio.file.Path; -import java.util.Objects; - -public record EditorProjectSnapshot( - Path projectRoot, - EditorProjectNode rootNode) { - public EditorProjectSnapshot { - projectRoot = Objects.requireNonNull(projectRoot, "projectRoot").toAbsolutePath().normalize(); - rootNode = Objects.requireNonNull(rootNode, "rootNode"); - } -} diff --git a/prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorProjectSnapshotService.java b/prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorProjectSnapshotService.java deleted file mode 100644 index bd2ec3c4..00000000 --- a/prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorProjectSnapshotService.java +++ /dev/null @@ -1,62 +0,0 @@ -package p.studio.workspaces.editor; - -import p.studio.compiler.FrontendRegistryService; -import p.studio.projects.ProjectReference; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.stream.Stream; - -public final class EditorProjectSnapshotService { - - public EditorProjectSnapshot createSnapshot(final ProjectReference projectReference) { - final var project = Objects.requireNonNull(projectReference, "projectReference"); - final var projectRoot = project.rootPath().toAbsolutePath().normalize(); - final var taggedRoots = taggedSourceRoots(project); - final var rootNode = buildNode(projectRoot, project.name(), taggedRoots); - return new EditorProjectSnapshot(projectRoot, rootNode); - } - - private Set taggedSourceRoots(final ProjectReference projectReference) { - return FrontendRegistryService.getFrontendSpec(projectReference.languageId()) - .stream() - .flatMap(frontendSpec -> frontendSpec.getSourceRoots().stream()) - .map(projectReference.rootPath()::resolve) - .map(Path::toAbsolutePath) - .map(Path::normalize) - .collect(java.util.stream.Collectors.toSet()); - } - - private EditorProjectNode buildNode( - final Path path, - final String displayName, - final Set taggedRoots) { - if (!Files.isDirectory(path)) { - return new EditorProjectNode(path, displayName, false, taggedRoots.contains(path), List.of()); - } - - final List children; - try (Stream stream = Files.list(path)) { - children = stream - .sorted(nodeComparator()) - .map(child -> buildNode(child, child.getFileName().toString(), taggedRoots)) - .toList(); - } catch (IOException ioException) { - throw new UncheckedIOException(ioException); - } - - return new EditorProjectNode(path, displayName, true, taggedRoots.contains(path), children); - } - - private Comparator nodeComparator() { - return Comparator - .comparing((Path path) -> !Files.isDirectory(path)) - .thenComparing(path -> path.getFileName().toString(), String.CASE_INSENSITIVE_ORDER); - } -} diff --git a/prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorWorkspace.java b/prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorWorkspace.java index 4cfd2686..5c56d681 100644 --- a/prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorWorkspace.java +++ b/prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorWorkspace.java @@ -12,6 +12,12 @@ import p.studio.projects.ProjectReference; import p.studio.utilities.i18n.I18n; import p.studio.workspaces.Workspace; import p.studio.workspaces.WorkspaceId; +import p.studio.vfs.ProjectDocumentVfs; +import p.studio.vfs.VfsDocumentOpenResult; +import p.studio.vfs.VfsProjectNode; +import p.studio.vfs.VfsTextDocument; + +import java.util.Objects; public final class EditorWorkspace extends Workspace { private final BorderPane root = new BorderPane(); @@ -21,12 +27,14 @@ public final class EditorWorkspace extends Workspace { private final EditorHelperPanel helperPanel = new EditorHelperPanel(); private final EditorStatusBar statusBar = new EditorStatusBar(); private final EditorTabStrip tabStrip = new EditorTabStrip(); - private final EditorProjectSnapshotService snapshotService = new EditorProjectSnapshotService(); - private final EditorFileBufferLoader fileBufferLoader = new EditorFileBufferLoader(); + private final ProjectDocumentVfs projectDocumentVfs; private final EditorOpenFileSession openFileSession = new EditorOpenFileSession(); - public EditorWorkspace(final ProjectReference projectReference) { + public EditorWorkspace( + final ProjectReference projectReference, + final ProjectDocumentVfs projectDocumentVfs) { super(projectReference); + this.projectDocumentVfs = Objects.requireNonNull(projectDocumentVfs, "projectDocumentVfs"); root.getStyleClass().add("editor-workspace"); codeArea.setParagraphGraphicFactory(LineNumberFactory.get(codeArea)); codeArea.setEditable(false); @@ -62,16 +70,24 @@ public final class EditorWorkspace extends Workspace { public CodeArea codeArea() { return codeArea; } private void refreshNavigator() { - navigatorPanel.setSnapshot(snapshotService.createSnapshot(projectReference)); + navigatorPanel.setSnapshot(projectDocumentVfs.refresh()); } - private void openNode(final EditorProjectNode node) { - fileBufferLoader.load(node.path()) - .ifPresentOrElse(this::openFile, () -> showUnsupportedFileModal(node.path())); + private void openNode(final VfsProjectNode node) { + final VfsDocumentOpenResult result = projectDocumentVfs.openDocument(node.path()); + if (result instanceof VfsTextDocument textDocument) { + openFile(textDocument); + return; + } + showUnsupportedFileModal(node.path()); } - private void openFile(final EditorOpenFileBuffer fileBuffer) { - openFileSession.open(fileBuffer); + private void openFile(final VfsTextDocument textDocument) { + openFileSession.open(new EditorOpenFileBuffer( + textDocument.path(), + textDocument.documentName(), + textDocument.content(), + textDocument.lineSeparator())); renderSession(); } diff --git a/prometeu-studio/src/test/java/p/studio/workspaces/editor/EditorFileBufferLoaderTest.java b/prometeu-studio/src/test/java/p/studio/workspaces/editor/EditorFileBufferLoaderTest.java deleted file mode 100644 index 364d9385..00000000 --- a/prometeu-studio/src/test/java/p/studio/workspaces/editor/EditorFileBufferLoaderTest.java +++ /dev/null @@ -1,37 +0,0 @@ -package p.studio.workspaces.editor; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.jupiter.api.Assertions.*; - -final class EditorFileBufferLoaderTest { - @TempDir - Path tempDir; - - @Test - void loadReturnsReadOnlyTextBufferForUtf8TextFile() throws Exception { - final var file = tempDir.resolve("main.pbs"); - Files.writeString(file, "fn main(): void\n"); - - final var result = new EditorFileBufferLoader().load(file); - - assertTrue(result.isPresent()); - assertEquals("main.pbs", result.get().tabLabel()); - assertEquals("LF", result.get().lineSeparator()); - assertTrue(result.get().content().contains("fn main()")); - } - - @Test - void loadRejectsBinaryLikeFile() throws Exception { - final var file = tempDir.resolve("sprite.bin"); - Files.write(file, new byte[]{0x01, 0x00, 0x02}); - - final var result = new EditorFileBufferLoader().load(file); - - assertTrue(result.isEmpty()); - } -} diff --git a/prometeu-studio/src/test/java/p/studio/workspaces/editor/EditorProjectSnapshotServiceTest.java b/prometeu-studio/src/test/java/p/studio/workspaces/editor/EditorProjectSnapshotServiceTest.java deleted file mode 100644 index b1c27451..00000000 --- a/prometeu-studio/src/test/java/p/studio/workspaces/editor/EditorProjectSnapshotServiceTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package p.studio.workspaces.editor; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; -import p.studio.projects.ProjectReference; - -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.junit.jupiter.api.Assertions.*; - -final class EditorProjectSnapshotServiceTest { - @TempDir - Path tempDir; - - @Test - void snapshotIncludesHiddenFilesOrdersFoldersFirstAndTagsSourceRoots() throws Exception { - Files.createDirectories(tempDir.resolve("src")); - Files.createDirectories(tempDir.resolve("assets")); - Files.writeString(tempDir.resolve(".env"), "TOKEN=1\n"); - Files.writeString(tempDir.resolve("README.md"), "# project\n"); - - final var snapshot = new EditorProjectSnapshotService().createSnapshot(new ProjectReference( - "Example", - "1.0.0", - "pbs", - 1, - tempDir)); - - assertEquals("Example", snapshot.rootNode().displayName()); - assertEquals("assets", snapshot.rootNode().children().get(0).displayName()); - assertEquals("src", snapshot.rootNode().children().get(1).displayName()); - assertEquals(".env", snapshot.rootNode().children().get(2).displayName()); - assertTrue(snapshot.rootNode().children().get(1).taggedSourceRoot()); - } -}