Created
February 11, 2026 10:06
-
-
Save musketyr/0325e16325972ae46cef93a37e440c33 to your computer and use it in GitHub Desktop.
Spock to JUnit 5 migration diff - sc185874
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: RoiKeyPerformanceMetricsSpec</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; } | |
| .summary { background: #c6f6d5; border-left: 4px solid #38a169; padding: 12px 16px; margin: 0; } | |
| .summary p { color: #276749; font-size: 14px; } | |
| .summary strong { color: #22543d; } | |
| @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: RoiKeyPerformanceMetricsSpec</h1> | |
| <p style="text-align: center; color: #666; margin-bottom: 20px;">Story: <a href="https://app.shortcut.com/agorapulse/story/185874">sc185874</a> | PR: <a href="https://github.com/agorapulse/platform/pull/72703">#72703</a></p> | |
| <!-- Section: Imports --> | |
| <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.core.models | |
| import agorapulse.report.client.PostInsightSummary | |
| import agorapulse.report.client.insights.PostInsightAttachment | |
| import agorapulse.service.client.api.Service | |
| import spock.lang.Specification | |
| import java.time.Instant | |
| import java.time.LocalDateTime | |
| import java.time.ZoneOffset</pre> | |
| </div> | |
| <div class="diff-panel right"> | |
| <h3>JUnit 5 (Java)</h3> | |
| <pre>package agorapulse.roi.core.models; | |
| import agorapulse.report.client.PostInsightSummary; | |
| import agorapulse.report.client.insights.PostInsightAttachment; | |
| import org.junit.jupiter.api.Test; | |
| import java.math.BigDecimal; | |
| import java.time.Instant; | |
| import java.time.LocalDateTime; | |
| import java.time.ZoneOffset; | |
| import static org.assertj.core.api.Assertions.assertThat;</pre> | |
| </div> | |
| </div> | |
| <div class="summary"> | |
| <p><strong>Changes:</strong> Removed Spock import, unused Service import. Added JUnit 5 @Test, BigDecimal (explicit), and AssertJ static import.</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Section: Class Declaration --> | |
| <div class="section"> | |
| <div class="section-header" onclick="toggleSection(this)"> | |
| <h2>🏗️ Class Declaration</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 RoiKeyPerformanceMetricsSpec extends Specification {</pre> | |
| </div> | |
| <div class="diff-panel right"> | |
| <h3>JUnit 5 (Java)</h3> | |
| <pre>class RoiKeyPerformanceMetricsTest {</pre> | |
| </div> | |
| </div> | |
| <div class="summary"> | |
| <p><strong>Changes:</strong> Removed Specification inheritance (no mocks needed). Renamed Spec → Test.</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Section: Test 1 - Increment --> | |
| <div class="section"> | |
| <div class="section-header" onclick="toggleSection(this)"> | |
| <h2>🧪 Test: shouldIncrementRoiKeyPerformanceMetrics</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 increment roi key performance metrics'() { | |
| given: | |
| RoiKeyPerformanceMetrics givenMetrics = RoiKeyPerformanceMetrics.builder() | |
| .conversionGoalCount(1L) | |
| .conversionTransactionsCount(1L) | |
| .generatedRevenueGoalCount(BigDecimal.ONE) | |
| .generatedRevenueTransactionsCount(BigDecimal.ONE) | |
| .visitorCount(1L) | |
| .conversionGoalRatio(BigDecimal.ONE) | |
| .conversionTransactionsRatio(BigDecimal.ONE) | |
| .generatedRevenueGoalRatio(BigDecimal.ONE) | |
| .generatedRevenueTransactionsRatio(BigDecimal.ONE) | |
| .visitorRatio(BigDecimal.ONE) | |
| .build() | |
| RoiKeyPerformanceMetrics metrics = RoiKeyPerformanceMetrics.builder() | |
| .conversionGoalCount(10L) | |
| .conversionTransactionsCount(10L) | |
| .generatedRevenueGoalCount(BigDecimal.TEN) | |
| .generatedRevenueTransactionsCount(BigDecimal.TEN) | |
| .visitorCount(10L) | |
| .conversionGoalRatio(BigDecimal.TEN) | |
| .conversionTransactionsRatio(BigDecimal.TEN) | |
| .generatedRevenueGoalRatio(BigDecimal.TEN) | |
| .generatedRevenueTransactionsRatio(BigDecimal.TEN) | |
| .visitorRatio(BigDecimal.TEN) | |
| .build() | |
| when: | |
| givenMetrics.increment(metrics) | |
| then: | |
| givenMetrics.with { | |
| conversionGoalCount == 11L | |
| conversionTransactionsCount == 11L | |
| generatedRevenueGoalCount == BigDecimal.valueOf(11) | |
| generatedRevenueTransactionsCount == BigDecimal.valueOf(11) | |
| visitorCount == 11L | |
| conversionGoalRatio == BigDecimal.valueOf(11) | |
| conversionTransactionsRatio == BigDecimal.valueOf(11) | |
| generatedRevenueGoalRatio == BigDecimal.valueOf(11) | |
| generatedRevenueTransactionsRatio == BigDecimal.valueOf(11) | |
| visitorRatio == BigDecimal.valueOf(11) | |
| } | |
| }</pre> | |
| </div> | |
| <div class="diff-panel right"> | |
| <h3>JUnit 5 (Java)</h3> | |
| <pre>@Test | |
| void shouldIncrementRoiKeyPerformanceMetrics() { | |
| // given | |
| RoiKeyPerformanceMetrics givenMetrics = RoiKeyPerformanceMetrics.builder() | |
| .conversionGoalCount(1L) | |
| .conversionTransactionsCount(1L) | |
| .generatedRevenueGoalCount(BigDecimal.ONE) | |
| .generatedRevenueTransactionsCount(BigDecimal.ONE) | |
| .visitorCount(1L) | |
| .conversionGoalRatio(BigDecimal.ONE) | |
| .conversionTransactionsRatio(BigDecimal.ONE) | |
| .generatedRevenueGoalRatio(BigDecimal.ONE) | |
| .generatedRevenueTransactionsRatio(BigDecimal.ONE) | |
| .visitorRatio(BigDecimal.ONE) | |
| .build(); | |
| RoiKeyPerformanceMetrics metrics = RoiKeyPerformanceMetrics.builder() | |
| .conversionGoalCount(10L) | |
| .conversionTransactionsCount(10L) | |
| .generatedRevenueGoalCount(BigDecimal.TEN) | |
| .generatedRevenueTransactionsCount(BigDecimal.TEN) | |
| .visitorCount(10L) | |
| .conversionGoalRatio(BigDecimal.TEN) | |
| .conversionTransactionsRatio(BigDecimal.TEN) | |
| .generatedRevenueGoalRatio(BigDecimal.TEN) | |
| .generatedRevenueTransactionsRatio(BigDecimal.TEN) | |
| .visitorRatio(BigDecimal.TEN) | |
| .build(); | |
| // when | |
| givenMetrics.increment(metrics); | |
| // then | |
| assertThat(givenMetrics.getConversionGoalCount()).isEqualTo(11L); | |
| assertThat(givenMetrics.getConversionTransactionsCount()).isEqualTo(11L); | |
| assertThat(givenMetrics.getGeneratedRevenueGoalCount()).isEqualByComparingTo(BigDecimal.valueOf(11)); | |
| assertThat(givenMetrics.getGeneratedRevenueTransactionsCount()).isEqualByComparingTo(BigDecimal.valueOf(11)); | |
| assertThat(givenMetrics.getVisitorCount()).isEqualTo(11L); | |
| assertThat(givenMetrics.getConversionGoalRatio()).isEqualByComparingTo(BigDecimal.valueOf(11)); | |
| assertThat(givenMetrics.getConversionTransactionsRatio()).isEqualByComparingTo(BigDecimal.valueOf(11)); | |
| assertThat(givenMetrics.getGeneratedRevenueGoalRatio()).isEqualByComparingTo(BigDecimal.valueOf(11)); | |
| assertThat(givenMetrics.getGeneratedRevenueTransactionsRatio()).isEqualByComparingTo(BigDecimal.valueOf(11)); | |
| assertThat(givenMetrics.getVisitorRatio()).isEqualByComparingTo(BigDecimal.valueOf(11)); | |
| }</pre> | |
| </div> | |
| </div> | |
| <div class="summary"> | |
| <p><strong>Changes:</strong> Added @Test annotation, camelCase method name. Replaced Groovy <code>with</code> block with explicit AssertJ assertions using getters. Used <code>isEqualByComparingTo</code> for BigDecimal comparisons.</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Section: Test 2 - Calculate Ratio --> | |
| <div class="section"> | |
| <div class="section-header" onclick="toggleSection(this)"> | |
| <h2>🧪 Test: shouldCalculateRatioOfRoiKeyPerformanceMetrics</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 calculate ratio of roi key performance metrics'() { | |
| given: | |
| RoiKeyPerformanceMetrics givenMetrics = RoiKeyPerformanceMetrics.builder() | |
| .conversionGoalCount(1L) | |
| .conversionTransactionsCount(1L) | |
| .generatedRevenueGoalCount(BigDecimal.ONE) | |
| .generatedRevenueTransactionsCount(BigDecimal.ONE) | |
| .visitorCount(1L) | |
| .build() | |
| Performance performance = Performance.builder() | |
| .conversionGoalCount(10L) | |
| .conversionTransactionsCount(10L) | |
| .generatedRevenueGoalCount(BigDecimal.TEN) | |
| .generatedRevenueTransactionsCount(BigDecimal.TEN) | |
| .visitorCount(10L) | |
| .build() | |
| when: | |
| givenMetrics.calculateRatio(performance) | |
| then: | |
| givenMetrics.with { | |
| conversionGoalCount == 1L | |
| conversionTransactionsCount == 1L | |
| generatedRevenueGoalCount == BigDecimal.ONE | |
| generatedRevenueTransactionsCount == BigDecimal.ONE | |
| visitorCount == 1L | |
| conversionGoalRatio == BigDecimal.TEN | |
| conversionTransactionsRatio == BigDecimal.TEN | |
| generatedRevenueGoalRatio == BigDecimal.TEN | |
| generatedRevenueTransactionsRatio == BigDecimal.TEN | |
| visitorRatio == BigDecimal.TEN | |
| } | |
| }</pre> | |
| </div> | |
| <div class="diff-panel right"> | |
| <h3>JUnit 5 (Java)</h3> | |
| <pre>@Test | |
| void shouldCalculateRatioOfRoiKeyPerformanceMetrics() { | |
| // given | |
| RoiKeyPerformanceMetrics givenMetrics = RoiKeyPerformanceMetrics.builder() | |
| .conversionGoalCount(1L) | |
| .conversionTransactionsCount(1L) | |
| .generatedRevenueGoalCount(BigDecimal.ONE) | |
| .generatedRevenueTransactionsCount(BigDecimal.ONE) | |
| .visitorCount(1L) | |
| .build(); | |
| Performance performance = Performance.builder() | |
| .conversionGoalCount(10L) | |
| .conversionTransactionsCount(10L) | |
| .generatedRevenueGoalCount(BigDecimal.TEN) | |
| .generatedRevenueTransactionsCount(BigDecimal.TEN) | |
| .visitorCount(10L) | |
| .build(); | |
| // when | |
| givenMetrics.calculateRatio(performance); | |
| // then | |
| assertThat(givenMetrics.getConversionGoalCount()).isEqualTo(1L); | |
| assertThat(givenMetrics.getConversionTransactionsCount()).isEqualTo(1L); | |
| assertThat(givenMetrics.getGeneratedRevenueGoalCount()).isEqualByComparingTo(BigDecimal.ONE); | |
| assertThat(givenMetrics.getGeneratedRevenueTransactionsCount()).isEqualByComparingTo(BigDecimal.ONE); | |
| assertThat(givenMetrics.getVisitorCount()).isEqualTo(1L); | |
| assertThat(givenMetrics.getConversionGoalRatio()).isEqualByComparingTo(BigDecimal.TEN); | |
| assertThat(givenMetrics.getConversionTransactionsRatio()).isEqualByComparingTo(BigDecimal.TEN); | |
| assertThat(givenMetrics.getGeneratedRevenueGoalRatio()).isEqualByComparingTo(BigDecimal.TEN); | |
| assertThat(givenMetrics.getGeneratedRevenueTransactionsRatio()).isEqualByComparingTo(BigDecimal.TEN); | |
| assertThat(givenMetrics.getVisitorRatio()).isEqualByComparingTo(BigDecimal.TEN); | |
| }</pre> | |
| </div> | |
| </div> | |
| <div class="summary"> | |
| <p><strong>Changes:</strong> Same pattern as above - @Test annotation, camelCase, explicit AssertJ assertions with getters.</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Section: Test 3 - Fill Post Insight --> | |
| <div class="section"> | |
| <div class="section-header" onclick="toggleSection(this)"> | |
| <h2>🧪 Test: shouldFillPerformanceWithPostInsight</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 fill performance with post insight'() { | |
| given: | |
| Instant date = LocalDateTime.of(2023, 12, 18, 0, 0).toInstant(ZoneOffset.UTC) | |
| PostInsightSummary postInsightSummary = new PostInsightSummary( | |
| publishingDate: date, | |
| message: 'test message', | |
| attachment: new PostInsightAttachment(url: 'https://fitter-today.com'), | |
| ) | |
| RoiKeyPerformanceMetrics metric = new RoiKeyPerformanceMetrics() | |
| when: | |
| metric.fillPostInsight(postInsightSummary) | |
| then: | |
| metric.with { | |
| publishingDate == date | |
| name == 'test message' | |
| pictureUrl == 'https://fitter-today.com' | |
| } | |
| }</pre> | |
| </div> | |
| <div class="diff-panel right"> | |
| <h3>JUnit 5 (Java)</h3> | |
| <pre>@Test | |
| void shouldFillPerformanceWithPostInsight() { | |
| // given | |
| Instant date = LocalDateTime.of(2023, 12, 18, 0, 0).toInstant(ZoneOffset.UTC); | |
| PostInsightAttachment attachment = new PostInsightAttachment(); | |
| attachment.setUrl("https://fitter-today.com"); | |
| PostInsightSummary postInsightSummary = new PostInsightSummary(); | |
| postInsightSummary.setPublishingDate(date); | |
| postInsightSummary.setMessage("test message"); | |
| postInsightSummary.setAttachment(attachment); | |
| RoiKeyPerformanceMetrics metric = new RoiKeyPerformanceMetrics(); | |
| // when | |
| metric.fillPostInsight(postInsightSummary); | |
| // then | |
| assertThat(metric.getPublishingDate()).isEqualTo(date); | |
| assertThat(metric.getName()).isEqualTo("test message"); | |
| assertThat(metric.getPictureUrl()).isEqualTo("https://fitter-today.com"); | |
| }</pre> | |
| </div> | |
| </div> | |
| <div class="summary"> | |
| <p><strong>Changes:</strong> Replaced Groovy map-style constructor with explicit setters. Replaced <code>with</code> block with AssertJ assertions using getters.</p> | |
| </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