Created
February 19, 2026 05:44
-
-
Save musketyr/dc00716b6f792bff7a864ce0e477e920 to your computer and use it in GitHub Desktop.
Spock to JUnit 5 Migration Diff
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Spock → JUnit 5 Migration: RoiPdfCapabilitiesSpec</title> | |
| <style> | |
| * { box-sizing: border-box; margin: 0; padding: 0; } | |
| body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #f5f5f5; padding: 20px; line-height: 1.6; } | |
| h1 { text-align: center; margin-bottom: 20px; color: #333; } | |
| .section { background: white; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); overflow: hidden; } | |
| .section-header { background: #2d3748; color: white; padding: 12px 16px; cursor: pointer; display: flex; justify-content: space-between; align-items: center; } | |
| .section-header:hover { background: #4a5568; } | |
| .section-header h2 { font-size: 16px; font-weight: 600; } | |
| .section-header .toggle { font-size: 12px; } | |
| .section-content { display: block; } | |
| .section-content.collapsed { display: none; } | |
| .diff-container { display: grid; grid-template-columns: 1fr 1fr; } | |
| .diff-panel { padding: 16px; overflow-x: auto; } | |
| .diff-panel.left { background: #fff5f5; border-right: 1px solid #e2e8f0; } | |
| .diff-panel.right { background: #f0fff4; } | |
| .diff-panel h3 { font-size: 12px; text-transform: uppercase; color: #718096; margin-bottom: 12px; letter-spacing: 0.5px; } | |
| pre { font-family: 'SF Mono', Monaco, 'Courier New', monospace; font-size: 13px; white-space: pre-wrap; word-wrap: break-word; } | |
| .left pre { color: #c53030; } | |
| .right pre { color: #276749; } | |
| @media (max-width: 768px) { .diff-container { grid-template-columns: 1fr; } .diff-panel.left { border-right: none; border-bottom: 1px solid #e2e8f0; } } | |
| </style> | |
| </head> | |
| <body> | |
| <h1>🦀 Spock → JUnit 5 Migration: RoiPdfCapabilitiesSpec</h1> | |
| <p style="text-align: center; color: #666; margin-bottom: 20px;">Story: <a href="https://app.shortcut.com/agorapulse/story/185888">sc185888</a> | PR: <a href="https://github.com/agorapulse/platform/pull/72988">#72988</a></p> | |
| <div class="section"> | |
| <div class="section-header" onclick="toggleSection(this)"> | |
| <h2>📦 Imports</h2> | |
| <span class="toggle">▼</span> | |
| </div> | |
| <div class="section-content"> | |
| <div class="diff-container"> | |
| <div class="diff-panel left"> | |
| <h3>Spock (Groovy)</h3> | |
| <pre>package agorapulse.roi.pdf.export.utils | |
| import agorapulse.commons.chart.models.HighchartsExporterParameters | |
| import agorapulse.commons.export.ExportSettingsDTO | |
| import agorapulse.commons.export.pdf.models.PdfDocument | |
| import agorapulse.commons.export.pdf.models.PdfMetric | |
| import agorapulse.commons.export.services.ImageService | |
| import agorapulse.commons.messagesource.interpolation.InterpolatingMessageSource | |
| import agorapulse.roi.core.models.Roi | |
| import agorapulse.roi.pdf.chart.generators.RoiHighchartsService | |
| import agorapulse.roi.pdf.chart.models.RoiSection | |
| import agorapulse.roi.pdf.export.generators.RoiPdfService | |
| import com.lowagie.text.Document | |
| import com.lowagie.text.PageSize | |
| import spock.lang.Specification | |
| import javax.imageio.ImageIO | |
| import java.awt.image.BufferedImage</pre> | |
| </div> | |
| <div class="diff-panel right"> | |
| <h3>JUnit 5 (Java)</h3> | |
| <pre>package agorapulse.roi.pdf.export.utils; | |
| import agorapulse.commons.chart.models.HighchartsExporterParameters; | |
| import agorapulse.commons.export.ExportSettingsDTO; | |
| import agorapulse.commons.export.pdf.models.PdfDocument; | |
| import agorapulse.commons.export.pdf.models.PdfMetric; | |
| import agorapulse.commons.export.services.ImageService; | |
| import agorapulse.commons.messagesource.interpolation.InterpolatingMessageSource; | |
| import agorapulse.roi.core.models.Roi; | |
| import agorapulse.roi.pdf.chart.generators.RoiHighchartsService; | |
| import agorapulse.roi.pdf.chart.models.RoiSection; | |
| import agorapulse.roi.pdf.export.generators.RoiPdfService; | |
| import com.lowagie.text.Document; | |
| import com.lowagie.text.PageSize; | |
| import org.junit.jupiter.api.BeforeEach; | |
| import org.junit.jupiter.api.Test; | |
| import org.junit.jupiter.api.extension.ExtendWith; | |
| import org.mockito.Mock; | |
| import org.mockito.junit.jupiter.MockitoExtension; | |
| import javax.imageio.ImageIO; | |
| import java.awt.image.BufferedImage; | |
| import java.io.ByteArrayOutputStream; | |
| import java.io.IOException; | |
| import java.util.List; | |
| import java.util.Locale; | |
| import java.util.Map; | |
| import static org.assertj.core.api.Assertions.assertThat; | |
| import static org.assertj.core.api.Assertions.assertThatThrownBy; | |
| import static org.mockito.Mockito.verify; | |
| import static org.mockito.Mockito.verifyNoMoreInteractions; | |
| import static org.mockito.Mockito.when;</pre> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="section"> | |
| <div class="section-header" onclick="toggleSection(this)"> | |
| <h2>🏗️ Class & Fields</h2> | |
| <span class="toggle">▼</span> | |
| </div> | |
| <div class="section-content"> | |
| <div class="diff-container"> | |
| <div class="diff-panel left"> | |
| <h3>Spock (Groovy)</h3> | |
| <pre>class RoiPdfCapabilitiesSpec extends Specification { | |
| private static final byte[] RED_SQUARE = redSquare | |
| ImageService imageService = Mock() | |
| InterpolatingMessageSource interpolatingMessageSource = Mock() | |
| RoiHighchartsService roiHighchartsService = Mock() | |
| RoiPdfCapabilities service = new RoiPdfCapabilities(imageService, interpolatingMessageSource, roiHighchartsService) | |
| </pre> | |
| </div> | |
| <div class="diff-panel right"> | |
| <h3>JUnit 5 (Java)</h3> | |
| <pre>@ExtendWith(MockitoExtension.class) | |
| class RoiPdfCapabilitiesTest { | |
| private static final byte[] RED_SQUARE = createRedSquare(); | |
| @Mock | |
| private ImageService imageService; | |
| @Mock | |
| private InterpolatingMessageSource interpolatingMessageSource; | |
| @Mock | |
| private RoiHighchartsService roiHighchartsService; | |
| private RoiPdfCapabilities service; | |
| @BeforeEach | |
| void setUp() { | |
| service = new RoiPdfCapabilities(imageService, interpolatingMessageSource, roiHighchartsService); | |
| } | |
| </pre> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="section"> | |
| <div class="section-header" onclick="toggleSection(this)"> | |
| <h2>🧪 should addHighChartsToPage - exception</h2> | |
| <span class="toggle">▼</span> | |
| </div> | |
| <div class="section-content"> | |
| <div class="diff-container"> | |
| <div class="diff-panel left"> | |
| <h3>Spock (Groovy)</h3> | |
| <pre> void 'should addHighChartsToPage - exception'() { | |
| when: | |
| service.addHighChartsToPage(null, null, null, null, 80, 16, 12) | |
| then: | |
| thrown(IllegalArgumentException) | |
| }</pre> | |
| </div> | |
| <div class="diff-panel right"> | |
| <h3>JUnit 5 (Java)</h3> | |
| <pre> @Test | |
| void shouldThrowExceptionWhenAddHighChartsToPageWithNullRoi() { | |
| assertThatThrownBy(() -> service.addHighChartsToPage(null, null, null, null, 80, 16, 12)) | |
| .isInstanceOf(IllegalArgumentException.class); | |
| }</pre> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="section"> | |
| <div class="section-header" onclick="toggleSection(this)"> | |
| <h2>🧪 should addHighChartsToPage - exception 2</h2> | |
| <span class="toggle">▼</span> | |
| </div> | |
| <div class="section-content"> | |
| <div class="diff-container"> | |
| <div class="diff-panel left"> | |
| <h3>Spock (Groovy)</h3> | |
| <pre> void 'should addHighChartsToPage - exception 2'() { | |
| when: | |
| service.addHighChartsToPage(new Roi(), null, null, null, 80, 16, 12) | |
| then: | |
| thrown(IllegalArgumentException) | |
| }</pre> | |
| </div> | |
| <div class="diff-panel right"> | |
| <h3>JUnit 5 (Java)</h3> | |
| <pre> @Test | |
| void shouldThrowExceptionWhenAddHighChartsToPageWithNullAccountName() { | |
| assertThatThrownBy(() -> service.addHighChartsToPage(new Roi(), null, null, null, 80, 16, 12)) | |
| .isInstanceOf(IllegalArgumentException.class); | |
| }</pre> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="section"> | |
| <div class="section-header" onclick="toggleSection(this)"> | |
| <h2>🧪 should addHighChartsToPage</h2> | |
| <span class="toggle">▼</span> | |
| </div> | |
| <div class="section-content"> | |
| <div class="diff-container"> | |
| <div class="diff-panel left"> | |
| <h3>Spock (Groovy)</h3> | |
| <pre> void 'should addHighChartsToPage'() { | |
| given: | |
| Roi roi = new Roi(accountName: 'test') | |
| Document document = new Document(PageSize.A4.rotate()) | |
| PdfDocument pdf = RoiPdfService.initDocument(document, 'roi.pdf') | |
| ExportSettingsDTO settings = new ExportSettingsDTO(timeFormat: '24') | |
| List<RoiSection> sections = [RoiSection.VISITOR, RoiSection.GENERATED_REVENUE] | |
| HighchartsExporterParameters visitorsParams = new HighchartsExporterParameters(jsonConfig: [test: 2]) | |
| HighchartsExporterParameters revenueParams = new HighchartsExporterParameters(jsonConfig: [test: 3]) | |
| when: | |
| boolean ok = service.addHighChartsToPage(roi, pdf, settings, sections, 80, 16, 12) | |
| document.close() | |
| then: | |
| 1 * roiHighchartsService.buildHighchartsExportParameters(roi, settings, RoiSection.VISITOR) >> visitorsParams | |
| 1 * roiHighchartsService.generateGraph(visitorsParams, 'VISITOR') >> RED_SQUARE | |
| 1 * roiHighchartsService.buildHighchartsExportParameters(roi, settings, RoiSection.GENERATED_REVENUE) >> revenueParams | |
| 1 * roiHighchartsService.generateGraph(revenueParams, 'GENERATED_REVENUE') >> RED_SQUARE | |
| ok | |
| }</pre> | |
| </div> | |
| <div class="diff-panel right"> | |
| <h3>JUnit 5 (Java)</h3> | |
| <pre> @Test | |
| void shouldAddHighChartsToPage() { | |
| // given | |
| Roi roi = new Roi(); | |
| roi.setAccountName("test"); | |
| Document document = new Document(PageSize.A4.rotate()); | |
| PdfDocument pdf = RoiPdfService.initDocument(document, "roi.pdf"); | |
| ExportSettingsDTO settings = new ExportSettingsDTO(); | |
| settings.setTimeFormat("24"); | |
| List<RoiSection> sections = List.of(RoiSection.VISITOR, RoiSection.GENERATED_REVENUE); | |
| HighchartsExporterParameters visitorsParams = new HighchartsExporterParameters(); | |
| visitorsParams.setJsonConfig(Map.of("test", 2)); | |
| HighchartsExporterParameters revenueParams = new HighchartsExporterParameters(); | |
| revenueParams.setJsonConfig(Map.of("test", 3)); | |
| when(roiHighchartsService.buildHighchartsExportParameters(roi, settings, RoiSection.VISITOR)).thenReturn(visitorsParams); | |
| when(roiHighchartsService.generateGraph(visitorsParams, "VISITOR")).thenReturn(RED_SQUARE); | |
| when(roiHighchartsService.buildHighchartsExportParameters(roi, settings, RoiSection.GENERATED_REVENUE)).thenReturn(revenueParams); | |
| when(roiHighchartsService.generateGraph(revenueParams, "GENERATED_REVENUE")).thenReturn(RED_SQUARE); | |
| // when | |
| boolean ok = service.addHighChartsToPage(roi, pdf, settings, sections, 80, 16, 12); | |
| document.close(); | |
| // then | |
| assertThat(ok).isTrue(); | |
| }</pre> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="section"> | |
| <div class="section-header" onclick="toggleSection(this)"> | |
| <h2>🧪 should addHighChartsToPage - missing chart</h2> | |
| <span class="toggle">▼</span> | |
| </div> | |
| <div class="section-content"> | |
| <div class="diff-container"> | |
| <div class="diff-panel left"> | |
| <h3>Spock (Groovy)</h3> | |
| <pre> void 'should addHighChartsToPage - missing chart'() { | |
| given: | |
| Roi roi = new Roi(accountName: 'test') | |
| Document document = new Document(PageSize.A4.rotate()) | |
| PdfDocument pdf = RoiPdfService.initDocument(document, 'roi.pdf') | |
| ExportSettingsDTO settings = new ExportSettingsDTO(timeFormat: '24') | |
| List<RoiSection> sections = [RoiSection.VISITOR, RoiSection.GENERATED_REVENUE] | |
| HighchartsExporterParameters visitorsParams = new HighchartsExporterParameters(jsonConfig: [test: 2]) | |
| HighchartsExporterParameters revenueParams = new HighchartsExporterParameters(jsonConfig: [test: 3]) | |
| when: | |
| boolean ok = service.addHighChartsToPage(roi, pdf, settings, sections, 80, 16, 12) | |
| document.close() | |
| then: | |
| 1 * roiHighchartsService.buildHighchartsExportParameters(roi, settings, RoiSection.VISITOR) >> visitorsParams | |
| 1 * roiHighchartsService.generateGraph(visitorsParams, 'VISITOR') >> RED_SQUARE | |
| 1 * roiHighchartsService.buildHighchartsExportParameters(roi, settings, RoiSection.GENERATED_REVENUE) >> revenueParams | |
| 1 * roiHighchartsService.generateGraph(revenueParams, 'GENERATED_REVENUE') >> null | |
| !ok | |
| }</pre> | |
| </div> | |
| <div class="diff-panel right"> | |
| <h3>JUnit 5 (Java)</h3> | |
| <pre> @Test | |
| void shouldReturnFalseWhenAddHighChartsToPageWithMissingChart() { | |
| // given | |
| Roi roi = new Roi(); | |
| roi.setAccountName("test"); | |
| Document document = new Document(PageSize.A4.rotate()); | |
| PdfDocument pdf = RoiPdfService.initDocument(document, "roi.pdf"); | |
| ExportSettingsDTO settings = new ExportSettingsDTO(); | |
| settings.setTimeFormat("24"); | |
| List<RoiSection> sections = List.of(RoiSection.VISITOR, RoiSection.GENERATED_REVENUE); | |
| HighchartsExporterParameters visitorsParams = new HighchartsExporterParameters(); | |
| visitorsParams.setJsonConfig(Map.of("test", 2)); | |
| HighchartsExporterParameters revenueParams = new HighchartsExporterParameters(); | |
| revenueParams.setJsonConfig(Map.of("test", 3)); | |
| when(roiHighchartsService.buildHighchartsExportParameters(roi, settings, RoiSection.VISITOR)).thenReturn(visitorsParams); | |
| when(roiHighchartsService.generateGraph(visitorsParams, "VISITOR")).thenReturn(RED_SQUARE); | |
| when(roiHighchartsService.buildHighchartsExportParameters(roi, settings, RoiSection.GENERATED_REVENUE)).thenReturn(revenueParams); | |
| when(roiHighchartsService.generateGraph(revenueParams, "GENERATED_REVENUE")).thenReturn(null); | |
| // when | |
| boolean ok = service.addHighChartsToPage(roi, pdf, settings, sections, 80, 16, 12); | |
| document.close(); | |
| // then | |
| assertThat(ok).isFalse(); | |
| }</pre> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="section"> | |
| <div class="section-header" onclick="toggleSection(this)"> | |
| <h2>🧪 should createMetricPage - no data</h2> | |
| <span class="toggle">▼</span> | |
| </div> | |
| <div class="section-content"> | |
| <div class="diff-container"> | |
| <div class="diff-panel left"> | |
| <h3>Spock (Groovy)</h3> | |
| <pre> void 'should createMetricPage - no data'() { | |
| given: | |
| Roi roi = new Roi(accountName: 'test') | |
| Document document = new Document(PageSize.A4.rotate()) | |
| PdfDocument pdf = RoiPdfService.initDocument(document, 'roi.pdf') | |
| ExportSettingsDTO settings = new ExportSettingsDTO(timeFormat: '24') | |
| PdfMetric<RoiSection> pdfMetric = new PdfMetric<RoiSection>(sections: [RoiSection.VISITOR]) | |
| HighchartsExporterParameters visitorsParams = new HighchartsExporterParameters(jsonConfig: [test: 2]) | |
| when: | |
| service.createMetricPage(roi, pdf, settings, pdfMetric, 16, 12) | |
| document.close() | |
| then: | |
| 1 * roiHighchartsService.buildHighchartsExportParameters(roi, settings, RoiSection.VISITOR) >> visitorsParams | |
| 1 * roiHighchartsService.generateGraph(visitorsParams, 'VISITOR') >> null | |
| 1 * interpolatingMessageSource.get('analytics.pdf.data-unavailable', Locale.ENGLISH) >> 'Data unavailable' | |
| 0 * _ | |
| }</pre> | |
| </div> | |
| <div class="diff-panel right"> | |
| <h3>JUnit 5 (Java)</h3> | |
| <pre> @Test | |
| void shouldCreateMetricPageWithNoData() { | |
| // given | |
| Roi roi = new Roi(); | |
| roi.setAccountName("test"); | |
| Document document = new Document(PageSize.A4.rotate()); | |
| PdfDocument pdf = RoiPdfService.initDocument(document, "roi.pdf"); | |
| ExportSettingsDTO settings = new ExportSettingsDTO(); | |
| settings.setTimeFormat("24"); | |
| PdfMetric<RoiSection> pdfMetric = new PdfMetric<>(); | |
| pdfMetric.setSections(List.of(RoiSection.VISITOR)); | |
| HighchartsExporterParameters visitorsParams = new HighchartsExporterParameters(); | |
| visitorsParams.setJsonConfig(Map.of("test", 2)); | |
| when(roiHighchartsService.buildHighchartsExportParameters(roi, settings, RoiSection.VISITOR)).thenReturn(visitorsParams); | |
| when(roiHighchartsService.generateGraph(visitorsParams, "VISITOR")).thenReturn(null); | |
| when(interpolatingMessageSource.get("analytics.pdf.data-unavailable", Locale.ENGLISH)).thenReturn("Data unavailable"); | |
| // when | |
| service.createMetricPage(roi, pdf, settings, pdfMetric, 16, 12); | |
| document.close(); | |
| // then | |
| verify(interpolatingMessageSource).get("analytics.pdf.data-unavailable", Locale.ENGLISH); | |
| verifyNoMoreInteractions(interpolatingMessageSource); | |
| }</pre> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="section"> | |
| <div class="section-header" onclick="toggleSection(this)"> | |
| <h2>🧪 should createMetricPage - data</h2> | |
| <span class="toggle">▼</span> | |
| </div> | |
| <div class="section-content"> | |
| <div class="diff-container"> | |
| <div class="diff-panel left"> | |
| <h3>Spock (Groovy)</h3> | |
| <pre> void 'should createMetricPage - data'() { | |
| given: | |
| Roi roi = new Roi(accountName: 'test') | |
| Document document = new Document(PageSize.A4.rotate()) | |
| PdfDocument pdf = RoiPdfService.initDocument(document, 'roi.pdf') | |
| ExportSettingsDTO settings = new ExportSettingsDTO(timeFormat: '24') | |
| PdfMetric<RoiSection> pdfMetric = new PdfMetric<RoiSection>(sections: [RoiSection.VISITOR]) | |
| HighchartsExporterParameters visitorsParams = new HighchartsExporterParameters(jsonConfig: [test: 2]) | |
| when: | |
| service.createMetricPage(roi, pdf, settings, pdfMetric, 16, 12) | |
| document.close() | |
| then: | |
| 1 * roiHighchartsService.buildHighchartsExportParameters(roi, settings, RoiSection.VISITOR) >> visitorsParams | |
| 1 * roiHighchartsService.generateGraph(visitorsParams, 'VISITOR') >> RED_SQUARE | |
| 0 * _ | |
| }</pre> | |
| </div> | |
| <div class="diff-panel right"> | |
| <h3>JUnit 5 (Java)</h3> | |
| <pre> @Test | |
| void shouldCreateMetricPageWithData() { | |
| // given | |
| Roi roi = new Roi(); | |
| roi.setAccountName("test"); | |
| Document document = new Document(PageSize.A4.rotate()); | |
| PdfDocument pdf = RoiPdfService.initDocument(document, "roi.pdf"); | |
| ExportSettingsDTO settings = new ExportSettingsDTO(); | |
| settings.setTimeFormat("24"); | |
| PdfMetric<RoiSection> pdfMetric = new PdfMetric<>(); | |
| pdfMetric.setSections(List.of(RoiSection.VISITOR)); | |
| HighchartsExporterParameters visitorsParams = new HighchartsExporterParameters(); | |
| visitorsParams.setJsonConfig(Map.of("test", 2)); | |
| when(roiHighchartsService.buildHighchartsExportParameters(roi, settings, RoiSection.VISITOR)).thenReturn(visitorsParams); | |
| when(roiHighchartsService.generateGraph(visitorsParams, "VISITOR")).thenReturn(RED_SQUARE); | |
| // when | |
| service.createMetricPage(roi, pdf, settings, pdfMetric, 16, 12); | |
| document.close(); | |
| // then | |
| verifyNoMoreInteractions(interpolatingMessageSource); | |
| }</pre> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| function toggleSection(header) { | |
| const content = header.nextElementSibling; | |
| const toggle = header.querySelector('.toggle'); | |
| content.classList.toggle('collapsed'); | |
| toggle.textContent = content.classList.contains('collapsed') ? '▶' : '▼'; | |
| } | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment