diff --git a/src/fr/monlouyan/bakefile/tests/BakeTestRunner.java b/src/fr/monlouyan/bakefile/tests/BakeTestRunner.java index e3a49c9..25fc9db 100644 --- a/src/fr/monlouyan/bakefile/tests/BakeTestRunner.java +++ b/src/fr/monlouyan/bakefile/tests/BakeTestRunner.java @@ -5,8 +5,6 @@ import javax.swing.border.EmptyBorder; import javax.swing.table.DefaultTableModel; import javax.swing.text.DefaultCaret; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.io.*; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; @@ -55,76 +53,158 @@ public class BakeTestRunner extends JFrame { createLogsDirectory(); } - private void setupUI() { - mainPanel = new JPanel(new BorderLayout(10, 10)); - mainPanel.setBorder(new EmptyBorder(10, 10, 10, 10)); - - // Top panel with controls - JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 5)); - runSelectedButton = new JButton("Run Selected Tests"); - runAllButton = new JButton("Run All Tests"); - compareSelectedButton = new JButton("Compare Selected Test"); - languageComboBox = new JComboBox<>(new String[]{"All", "C", "Java"}); - openLogsButton = new JButton("Open Logs Directory"); - - controlPanel.add(runSelectedButton); - controlPanel.add(runAllButton); - controlPanel.add(compareSelectedButton); - controlPanel.add(new JLabel("Language:")); - controlPanel.add(languageComboBox); - controlPanel.add(openLogsButton); - - // Table for test list - String[] columnNames = {"#", "Language", "Test Name", "Status", "Last Run"}; - tableModel = new DefaultTableModel(columnNames, 0) { - @Override - public boolean isCellEditable(int row, int column) { - return false; - } - }; - testTable = new JTable(tableModel); - testTable.getColumnModel().getColumn(0).setPreferredWidth(30); - testTable.getColumnModel().getColumn(1).setPreferredWidth(70); - testTable.getColumnModel().getColumn(2).setPreferredWidth(300); - testTable.getColumnModel().getColumn(3).setPreferredWidth(80); - testTable.getColumnModel().getColumn(4).setPreferredWidth(150); - testTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); - testTable.setRowHeight(25); - - // Log area - logArea = new JTextArea(); - logArea.setEditable(false); - logArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12)); - DefaultCaret caret = (DefaultCaret) logArea.getCaret(); - caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE); - - // Progress bar - progressBar = new JProgressBar(0, 100); - progressBar.setStringPainted(true); - progressBar.setString("Ready"); - - // Layout - JSplitPane splitPane = new JSplitPane( - JSplitPane.VERTICAL_SPLIT, - new JScrollPane(testTable), - new JScrollPane(logArea) - ); - splitPane.setDividerLocation(300); - - mainPanel.add(controlPanel, BorderLayout.NORTH); - mainPanel.add(splitPane, BorderLayout.CENTER); - mainPanel.add(progressBar, BorderLayout.SOUTH); - - setContentPane(mainPanel); - - // Add action listeners - runSelectedButton.addActionListener(e -> runSelectedTests()); - runAllButton.addActionListener(e -> runAllTests()); - compareSelectedButton.addActionListener(e -> compareSelectedTest()); - openLogsButton.addActionListener(e -> openLogsDirectory()); - languageComboBox.addActionListener(e -> filterTestsByLanguage()); - } - + private void setupUI() { + mainPanel = new JPanel(new BorderLayout(10, 10)); + mainPanel.setBorder(new EmptyBorder(10, 10, 10, 10)); + + // Panel du haut avec contrôles modernisés + JPanel controlPanel = new JPanel(); + controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.Y_AXIS)); + + // Première ligne de contrôles + JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 5)); + runSelectedButton = new JButton("Run Selected Tests"); + runAllButton = new JButton("Run All Tests"); + compareSelectedButton = new JButton("Compare Selected Test"); + + // Styliser les boutons + runSelectedButton.setBackground(new Color(70, 130, 180)); // Steel Blue + runSelectedButton.setForeground(Color.WHITE); + runSelectedButton.setFont(new Font("Dialog", Font.BOLD, 12)); + + runAllButton.setBackground(new Color(60, 179, 113)); // Medium Sea Green + runAllButton.setForeground(Color.WHITE); + runAllButton.setFont(new Font("Dialog", Font.BOLD, 12)); + + compareSelectedButton.setBackground(new Color(30, 144, 255)); // Dodger Blue + compareSelectedButton.setForeground(Color.WHITE); + compareSelectedButton.setFont(new Font("Dialog", Font.BOLD, 12)); + + buttonPanel.add(runSelectedButton); + buttonPanel.add(runAllButton); + buttonPanel.add(compareSelectedButton); + + // Deuxième ligne de contrôles + JPanel filterPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 5)); + filterPanel.add(new JLabel("Language:")); + languageComboBox = new JComboBox<>(new String[]{"All", "C", "Java"}); + languageComboBox.setPreferredSize(new Dimension(100, 25)); + + openLogsButton = new JButton("Open Logs Directory"); + openLogsButton.setBackground(new Color(211, 211, 211)); // Light Gray + openLogsButton.setFont(new Font("Dialog", Font.PLAIN, 12)); + + filterPanel.add(languageComboBox); + filterPanel.add(Box.createHorizontalStrut(10)); + filterPanel.add(openLogsButton); + + controlPanel.add(buttonPanel); + controlPanel.add(Box.createVerticalStrut(5)); + controlPanel.add(filterPanel); + + // Tableau stylisé pour la liste des tests + String[] columnNames = {"#", "Language", "Test Name", "Status", "Last Run"}; + tableModel = new DefaultTableModel(columnNames, 0) { + @Override + public boolean isCellEditable(int row, int column) { + return false; + } + + @Override + public Class<?> getColumnClass(int column) { + if (column == 0) return Integer.class; + return String.class; + } + }; + + testTable = new JTable(tableModel) { + @Override + public Component prepareRenderer(javax.swing.table.TableCellRenderer renderer, int row, int column) { + Component comp = super.prepareRenderer(renderer, row, column); + + // Alterner les couleurs des lignes + if (!comp.getBackground().equals(getSelectionBackground())) { + String status = (String) getValueAt(row, 3); + if ("PASSED".equals(status)) { + comp.setBackground(PASSED_COLOR); + } else if ("FAILED".equals(status)) { + comp.setBackground(FAILED_COLOR); + } else if ("RUNNING".equals(status)) { + comp.setBackground(RUNNING_COLOR); + } else { + comp.setBackground(row % 2 == 0 ? new Color(240, 240, 250) : Color.WHITE); + } + } + return comp; + } + }; + + testTable.getColumnModel().getColumn(0).setPreferredWidth(30); + testTable.getColumnModel().getColumn(0).setMaxWidth(50); + testTable.getColumnModel().getColumn(1).setPreferredWidth(70); + testTable.getColumnModel().getColumn(1).setMaxWidth(100); + testTable.getColumnModel().getColumn(2).setPreferredWidth(300); + testTable.getColumnModel().getColumn(3).setPreferredWidth(80); + testTable.getColumnModel().getColumn(3).setMaxWidth(120); + testTable.getColumnModel().getColumn(4).setPreferredWidth(150); + + testTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + testTable.setRowHeight(28); + testTable.setShowGrid(false); + testTable.setIntercellSpacing(new Dimension(0, 0)); + testTable.getTableHeader().setFont(new Font("Dialog", Font.BOLD, 12)); + testTable.getTableHeader().setOpaque(false); + testTable.getTableHeader().setBackground(new Color(240, 240, 240)); + testTable.setFont(new Font("Dialog", Font.PLAIN, 12)); + + // Zone de logs améliorée + logArea = new JTextArea(); + logArea.setEditable(false); + logArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12)); + logArea.setBackground(new Color(250, 250, 250)); + logArea.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + DefaultCaret caret = (DefaultCaret) logArea.getCaret(); + caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE); + + JPanel logPanel = new JPanel(new BorderLayout()); + logPanel.add(new JLabel(" Test Output:"), BorderLayout.NORTH); + logPanel.add(new JScrollPane(logArea), BorderLayout.CENTER); + + // Barre de progression stylisée + progressBar = new JProgressBar(0, 100); + progressBar.setStringPainted(true); + progressBar.setString("Ready"); + progressBar.setFont(new Font("Dialog", Font.BOLD, 11)); + progressBar.setForeground(new Color(46, 139, 87)); // Sea Green + + // Layout + JSplitPane splitPane = new JSplitPane( + JSplitPane.VERTICAL_SPLIT, + new JScrollPane(testTable), + logPanel + ); + splitPane.setDividerLocation(300); + splitPane.setContinuousLayout(true); + splitPane.setDividerSize(5); + + mainPanel.add(controlPanel, BorderLayout.NORTH); + mainPanel.add(splitPane, BorderLayout.CENTER); + + JPanel statusPanel = new JPanel(new BorderLayout()); + statusPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); + statusPanel.add(progressBar, BorderLayout.CENTER); + mainPanel.add(statusPanel, BorderLayout.SOUTH); + + setContentPane(mainPanel); + + // Add action listeners + runSelectedButton.addActionListener(e -> runSelectedTests()); + runAllButton.addActionListener(e -> runAllTests()); + compareSelectedButton.addActionListener(e -> compareSelectedTest()); + openLogsButton.addActionListener(e -> openLogsDirectory()); + languageComboBox.addActionListener(e -> filterTestsByLanguage()); + } + private void createLogsDirectory() { try { Files.createDirectories(Paths.get(logsDir)); @@ -169,74 +249,130 @@ public class BakeTestRunner extends JFrame { showComparisonDialog(logFile, language, testName); } - private void showComparisonDialog(File logFile, String language, String testName) { - JDialog dialog = new JDialog(this, "Comparison: " + language + " - " + testName, true); - dialog.setLayout(new BorderLayout(10, 10)); - dialog.setSize(1000, 600); - dialog.setLocationRelativeTo(this); - - try { - List<String> lines = Files.readAllLines(logFile.toPath()); - String content = String.join("\n", lines); - - // Split content to make and bake sections if possible - String makeOutput = ""; - String bakeOutput = ""; - - // Basic parsing - can be enhanced for better splitting - int makeIndex = content.indexOf("=== Make Output ==="); - int bakeIndex = content.indexOf("=== Bake Output ==="); - int comparisonIndex = content.indexOf("=== Comparison Results ==="); - - if (makeIndex != -1 && bakeIndex != -1) { - makeOutput = content.substring(makeIndex, bakeIndex).trim(); - if (comparisonIndex != -1) { - bakeOutput = content.substring(bakeIndex, comparisonIndex).trim(); - } else { - bakeOutput = content.substring(bakeIndex).trim(); - } - } - - JTextArea makeArea = new JTextArea(makeOutput); - JTextArea bakeArea = new JTextArea(bakeOutput); - JTextArea comparisonArea = new JTextArea(); - - if (comparisonIndex != -1) { - comparisonArea.setText(content.substring(comparisonIndex).trim()); - } else { - comparisonArea.setText("No comparison results available."); - } - - makeArea.setEditable(false); - bakeArea.setEditable(false); - comparisonArea.setEditable(false); - - makeArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12)); - bakeArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12)); - comparisonArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12)); - - JTabbedPane tabbedPane = new JTabbedPane(); - tabbedPane.addTab("Make Output", new JScrollPane(makeArea)); - tabbedPane.addTab("Bake Output", new JScrollPane(bakeArea)); - tabbedPane.addTab("Comparison", new JScrollPane(comparisonArea)); - - dialog.add(tabbedPane, BorderLayout.CENTER); - - JButton closeButton = new JButton("Close"); - closeButton.addActionListener(e -> dialog.dispose()); - - JPanel buttonPanel = new JPanel(); - buttonPanel.add(closeButton); - dialog.add(buttonPanel, BorderLayout.SOUTH); - - dialog.setVisible(true); - - } catch (IOException e) { - JOptionPane.showMessageDialog(dialog, - "Error reading log file: " + e.getMessage(), - "Error", JOptionPane.ERROR_MESSAGE); - } + private void showComparisonDialog(File logFile, String language, String testName) { + JDialog dialog = new JDialog(this, "Comparison: " + language + " - " + testName, true); + dialog.setLayout(new BorderLayout(10, 10)); + dialog.setSize(1000, 600); + dialog.setLocationRelativeTo(this); + + try { + List<String> lines = Files.readAllLines(logFile.toPath()); + String content = String.join("\n", lines); + + // Split content to make and bake sections if possible + String makeOutput = ""; + String bakeOutput = ""; + String comparisonResults = ""; + + // Better parsing - enhanced for clearer splitting + int makeIndex = content.indexOf("=== Make Output ==="); + int bakeIndex = content.indexOf("=== Bake Output ==="); + int comparisonIndex = content.indexOf("=== Comparison Results ==="); + + if (makeIndex != -1 && bakeIndex != -1) { + makeOutput = content.substring(makeIndex, bakeIndex).trim(); + if (comparisonIndex != -1) { + bakeOutput = content.substring(bakeIndex, comparisonIndex).trim(); + comparisonResults = content.substring(comparisonIndex).trim(); + } else { + bakeOutput = content.substring(bakeIndex).trim(); + } + } + + JTextPane makeArea = createStyledTextPane(makeOutput); + JTextPane bakeArea = createStyledTextPane(bakeOutput); + JTextPane comparisonArea = createStyledTextPane( + comparisonIndex != -1 ? comparisonResults : "No comparison results available." + ); + + JTabbedPane tabbedPane = new JTabbedPane(); + tabbedPane.addTab("Make Output", new JScrollPane(makeArea)); + tabbedPane.addTab("Bake Output", new JScrollPane(bakeArea)); + tabbedPane.addTab("Comparison", new JScrollPane(comparisonArea)); + tabbedPane.setFont(new Font("Dialog", Font.PLAIN, 12)); + + // Détection et mise en évidence des différences + highlightDifferences(makeArea, bakeArea); + + dialog.add(tabbedPane, BorderLayout.CENTER); + + JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + JButton closeButton = new JButton("Close"); + closeButton.setFont(new Font("Dialog", Font.BOLD, 12)); + closeButton.addActionListener(e -> dialog.dispose()); + buttonPanel.add(closeButton); + + dialog.add(buttonPanel, BorderLayout.SOUTH); + dialog.setVisible(true); + + } catch (IOException e) { + JOptionPane.showMessageDialog(dialog, + "Error reading log file: " + e.getMessage(), + "Error", JOptionPane.ERROR_MESSAGE); + } + } + + // Méthode pour créer un JTextPane stylisé + private JTextPane createStyledTextPane(String content) { + JTextPane textPane = new JTextPane(); + textPane.setEditable(false); + textPane.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12)); + textPane.setText(content); + textPane.setMargin(new Insets(10, 10, 10, 10)); + textPane.setBackground(new Color(252, 252, 252)); + + // Appliquer une coloration syntaxique basique + highlightKeywords(textPane); + + return textPane; + } + +// Méthode pour mettre en évidence les mots clés +private void highlightKeywords(JTextPane textPane) { + // Obtenez le document et le kit de style + javax.swing.text.StyledDocument doc = textPane.getStyledDocument(); + javax.swing.text.Style defaultStyle = javax.swing.text.StyleContext.getDefaultStyleContext() + .getStyle(javax.swing.text.StyleContext.DEFAULT_STYLE); + + // Créez différents styles pour différents types de texte + javax.swing.text.Style errorStyle = doc.addStyle("errorStyle", defaultStyle); + javax.swing.text.StyleConstants.setForeground(errorStyle, new Color(220, 0, 0)); + javax.swing.text.StyleConstants.setBold(errorStyle, true); + + javax.swing.text.Style successStyle = doc.addStyle("successStyle", defaultStyle); + javax.swing.text.StyleConstants.setForeground(successStyle, new Color(0, 128, 0)); + javax.swing.text.StyleConstants.setBold(successStyle, true); + + // Appliquez les styles aux mots-clés + String text = textPane.getText(); + applyStyle(doc, text, "Error", errorStyle); + applyStyle(doc, text, "error", errorStyle); + applyStyle(doc, text, "ERROR", errorStyle); + applyStyle(doc, text, "failed", errorStyle); + applyStyle(doc, text, "FAILED", errorStyle); + + applyStyle(doc, text, "PASSED", successStyle); + applyStyle(doc, text, "passed", successStyle); + applyStyle(doc, text, "successful", successStyle); +} + +// Méthode auxiliaire pour appliquer un style à un mot-clé spécifique +private void applyStyle(javax.swing.text.StyledDocument doc, String text, String pattern, javax.swing.text.Style style) { + int pos = 0; + while ((pos = text.indexOf(pattern, pos)) >= 0) { + doc.setCharacterAttributes(pos, pattern.length(), style, true); + pos += pattern.length(); } +} + +// Méthode pour mettre en évidence les différences entre les sorties make et bake +private void highlightDifferences(JTextPane makeArea, JTextPane bakeArea) { + // Cette méthode devrait idéalement comparer les lignes et mettre en évidence les différences + // Pour une première implémentation simple, nous allons juste colorer les lignes contenant des erreurs + + highlightKeywords(makeArea); + highlightKeywords(bakeArea); +} private void loadTests() { tableModel.setRowCount(0);