|
144 | 144 | box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); /* shadow-lg */ |
145 | 145 | } |
146 | 146 |
|
| 147 | + .feature-card svg { |
| 148 | + height: 40px; |
| 149 | + margin-bottom: 1rem; |
| 150 | + fill: none; |
| 151 | + stroke: var(--spock-blue); |
| 152 | + stroke-width: 2; |
| 153 | + } |
| 154 | + |
147 | 155 | /* Additional Links Separator */ |
148 | 156 | .link-separator::after { |
149 | 157 | content: '|'; |
|
170 | 178 | </div> |
171 | 179 |
|
172 | 180 | <h1 class="text-4xl md:text-5xl lg:text-6xl font-bold mb-4 spock-blue-text" data-aos="fade-up"> |
173 | | - Write Beautiful & Expressive Tests |
| 181 | + Spock |
174 | 182 | </h1> |
175 | | - <p class="text-xl md:text-2xl text-gray-400 mb-8" data-aos="fade-up" data-aos-delay="100"> |
176 | | - Spock: The highly practical testing framework for Java and Groovy applications. |
177 | | - </p> |
178 | 183 | <p class="max-w-3xl mx-auto text-lg text-gray-300 mb-12" data-aos="fade-up" data-aos-delay="200"> |
179 | | - Spock combines the power of Behavior-Driven Development (BDD) with an elegant Groovy-based syntax. |
180 | | - Write tests that are not only powerful but also highly readable and maintainable, making collaboration easier and development faster. |
| 184 | + Spock is a testing, specification, and mocking framework for JVM developers that emphasizes readability and clarity. |
| 185 | + By blending BDD concepts and Groovy's concise syntax, Spock helps teams write tests that are not only easy to understand but also enjoyable to maintain. |
181 | 186 | </p> |
182 | 187 | </div> |
183 | 188 | </section> |
184 | 189 |
|
185 | | -<section class="py-16 md:py-24"> |
186 | | - <div class="container mx-auto px-6"> |
187 | | - <h2 class="text-3xl md:text-4xl font-bold text-center mb-12 text-gray-100" data-aos="fade-up"> |
188 | | - See How Readable Tests Can Be |
189 | | - </h2> |
190 | | - <div class="max-w-3xl mx-auto" data-aos="fade-up" data-aos-delay="100"> |
191 | | - <pre><code class="language-groovy"><span class="keyword">import</span> spock.lang.* |
192 | | - |
193 | | -<span class="keyword">class</span> <span class="class-name">MathSpec</span> <span class="keyword">extends</span> <span class="class-name">Specification</span> { |
194 | | - |
195 | | - <span class="class-name">def</span> <span class="string">"should add two numbers correctly"</span>() { |
196 | | - <span class="keyword">given:</span> <span class="string">"Setup preconditions"</span> |
197 | | - <span class="class-name">int</span> a = <span class="number">5</span> |
198 | | - <span class="class-name">int</span> b = <span class="number">3</span> |
199 | | - |
200 | | - <span class="keyword">when:</span> <span class="string">"Perform the action under test"</span> |
201 | | - <span class="class-name">int</span> result = a + b |
| 190 | +<section class="py-16 md:py-24"> <div class="container mx-auto px-6 text-center"> |
| 191 | + <h2 class="text-3xl md:text-4xl font-bold mb-8 text-gray-100" data-aos="fade-up">Ready to Improve Your Testing?</h2> |
202 | 192 |
|
203 | | - <span class="keyword">then:</span> <span class="string">"Assert the expected outcome"</span> |
204 | | - result == <span class="number">8</span> |
205 | | - } |
206 | | -} |
207 | | -</code></pre> |
208 | | - <p class="text-center text-gray-400 mt-6" data-aos="fade-up" data-aos-delay="200"> |
209 | | - Spock's clear <code class="inline-code">given:</code>, <code class="inline-code">when:</code>, <code class="inline-code">then:</code> blocks make understanding test logic intuitive. |
210 | | - </p> |
211 | | - </div> |
| 193 | + <div class="flex flex-col sm:flex-row justify-center items-center space-y-4 sm:space-y-0 sm:space-x-4" data-aos="fade-up" data-aos-delay="200"> |
| 194 | + <a href="https://groovyconsole.dev/?g=groovy_4_0&gist=437e9026ff86d2d709c2c56eb7e2eef1#g8qcDpYAQE" target="_blank" class="cta-button cta-primary"> |
| 195 | + Try it online |
| 196 | + </a> |
| 197 | + <a href="http://docs.spockframework.org" target="_blank" class="cta-button cta-secondary"> |
| 198 | + Read the Docs |
| 199 | + </a> |
| 200 | + <a href="https://github.com/spockframework/spock-example" target="_blank" class="cta-button cta-tertiary"> |
| 201 | + Clone the Example Project |
| 202 | + </a> |
212 | 203 | </div> |
| 204 | +</div> |
213 | 205 | </section> |
214 | 206 |
|
| 207 | + |
215 | 208 | <section class="py-16 md:py-24 bg-gray-800"> |
216 | 209 | <div class="container mx-auto px-6"> |
217 | 210 | <h2 class="text-3xl md:text-4xl font-bold text-center mb-16 text-gray-100" data-aos="fade-up"> |
218 | 211 | Why Choose Spock? |
219 | 212 | </h2> |
220 | 213 | <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8"> |
221 | 214 | <div class="feature-card" data-aos="fade-up" data-aos-delay="100"> |
| 215 | + <svg viewBox="0 0 24 24"><rect x="4" y="4" width="16" height="16" rx="2"/></svg> |
222 | 216 | <h3 class="text-xl font-semibold text-gray-100 mb-2">Expressive Specifications</h3> |
223 | 217 | <p class="text-gray-300">Write tests that are easy to read and understand, even for non-programmers.</p> |
224 | 218 | </div> |
225 | 219 | <div class="feature-card" data-aos="fade-up" data-aos-delay="150"> |
| 220 | + <svg viewBox="0 0 24 24"><path d="M3 17l6-6 4 4 8-8" /></svg> |
226 | 221 | <h3 class="text-xl font-semibold text-gray-100 mb-2">Powerful Mocking</h3> |
227 | 222 | <p class="text-gray-300">Create flexible and powerful mocks and stubs with built-in support.</p> |
228 | 223 | </div> |
229 | 224 | <div class="feature-card" data-aos="fade-up" data-aos-delay="200"> |
230 | | - <h3 class="text-xl font-semibold text-gray-100 mb-2">JUnit Runner</h3> |
231 | | - <p class="text-gray-300">Seamless integration with JUnit runners and build tools.</p> |
| 225 | + <svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" /><path d="M12 6v6l4 2" /></svg> |
| 226 | + <h3 class="text-xl font-semibold text-gray-100 mb-2">JUnit Platform</h3> |
| 227 | + <p class="text-gray-300">Seamless integration with JUnit Platform and build tools.</p> |
232 | 228 | </div> |
233 | 229 | <div class="feature-card" data-aos="fade-up" data-aos-delay="250"> |
| 230 | + <svg viewBox="0 0 24 24"><path d="M3 3h18v6H3zM3 15h18v6H3z" /><path d="M9 9v6" /></svg> |
234 | 231 | <h3 class="text-xl font-semibold text-gray-100 mb-2">Data-Driven Testing</h3> |
235 | 232 | <p class="text-gray-300">Easily run the same test with different sets of data.</p> |
236 | 233 | </div> |
237 | 234 | <div class="feature-card" data-aos="fade-up" data-aos-delay="300"> |
| 235 | + <svg viewBox="0 0 24 24"><polygon points="12 2 15 8 22 9 17 14 18 21 12 18 6 21 7 14 2 9 9 8 12 2" /></svg> |
238 | 236 | <h3 class="text-xl font-semibold text-gray-100 mb-2">Groovy DSL</h3> |
239 | 237 | <p class="text-gray-300">Leverage the power and flexibility of the Groovy language.</p> |
240 | 238 | </div> |
241 | 239 | <div class="feature-card" data-aos="fade-up" data-aos-delay="350"> |
| 240 | + <svg viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2" /><path d="M9 12l2 2 4-4" /></svg> |
242 | 241 | <h3 class="text-xl font-semibold text-gray-100 mb-2">Built-in Matchers</h3> |
243 | 242 | <p class="text-gray-300">Use a rich set of matchers to verify expectations with clarity.</p> |
244 | 243 | </div> |
245 | 244 | </div> |
246 | 245 | </div> |
247 | 246 | </section> |
248 | 247 |
|
249 | | -<section class="py-16 md:py-24"> <div class="container mx-auto px-6 text-center"> |
250 | | - <h2 class="text-3xl md:text-4xl font-bold mb-8 text-gray-100" data-aos="fade-up">Ready to Improve Your Testing?</h2> |
251 | | - <p class="text-lg text-gray-300 mb-12 max-w-2xl mx-auto" data-aos="fade-up" data-aos-delay="100"> |
252 | | - Explore the documentation, check out examples, or get started right away. |
253 | | - </p> |
| 248 | +<section class="py-16 md:py-24"> <div class="container mx-auto px-6"> |
| 249 | + <h2 class="text-3xl md:text-4xl font-bold text-center mb-12 text-gray-100" data-aos="fade-up"> |
| 250 | + See How Readable Tests Can Be |
| 251 | + </h2> |
| 252 | + <div class="max-w-3xl mx-auto" data-aos="fade-up" data-aos-delay="100"> |
| 253 | + <pre><code class="language-groovy"><span class="comment">// CalculatorSpec.groovy</span> |
| 254 | +<span class="keyword">import</span> spock.lang.Specification |
254 | 255 |
|
255 | | - <div class="flex flex-col sm:flex-row justify-center items-center space-y-4 sm:space-y-0 sm:space-x-4" data-aos="fade-up" data-aos-delay="200"> |
256 | | - <a href="https://groovyconsole.dev/?github=spockframework/spock/blob/6d2e6cc6475346f2fef256124e37f70514f0b98e/spock-specs/src/test/groovy/org/spockframework/docs/datadriven/v5/MathSpec.groovy#dgTIqWleyl" target="_blank" class="cta-button cta-primary"> |
257 | | - Try it online |
258 | | - </a> |
259 | | - <a href="http://docs.spockframework.org" target="_blank" class="cta-button cta-secondary"> |
260 | | - Read the Docs |
261 | | - </a> |
262 | | - <a href="https://github.com/spockframework/spock-example" target="_blank" class="cta-button cta-tertiary"> |
263 | | - Clone the Example Project |
264 | | - </a> |
| 256 | +<span class="keyword">class</span> <span class="class-name">CalculatorSpec</span> <span class="keyword">extends</span> Specification { |
| 257 | + |
| 258 | + <span class="keyword">def</span> <span class="string">"Test calculate method: #a #operation #b = #expectedResult"</span>() { |
| 259 | + <span class="keyword">given:</span> <span class="comment">"A calculator instance"</span> |
| 260 | + <span class="keyword">def</span> calculator = <span class="keyword">new</span> <span class="class-name">Calculator</span>() |
| 261 | + |
| 262 | + <span class="keyword">when:</span> <span class="comment">"Perform the calculation"</span> |
| 263 | + <span class="keyword">int</span> result = calculator.calculate(a, b, operation) |
| 264 | + |
| 265 | + <span class="keyword">then:</span> <span class="comment">"The result should match the expected value"</span> |
| 266 | + result == expectedResult |
| 267 | + |
| 268 | + <span class="keyword">where:</span> <span class="comment">"Define test data"</span> |
| 269 | + a | b | operation || expectedResult |
| 270 | + <span class="number">1</span> | <span class="number">2</span> | <span class="string">"+"</span> || <span class="number">3</span> |
| 271 | + <span class="number">5</span> | <span class="number">3</span> | <span class="string">"-"</span> || <span class="number">2</span> |
| 272 | + <span class="number">4</span> | <span class="number">2</span> | <span class="string">"*"</span> || <span class="number">8</span> |
| 273 | + <span class="number">10</span> | <span class="number">2</span> | <span class="string">"/"</span> || <span class="number">5</span> |
| 274 | + <span class="number">-1</span> | <span class="number">1</span> | <span class="string">"+"</span> || <span class="number">0</span> |
| 275 | + <span class="number">1</span> | <span class="number">-1</span> | <span class="string">"-"</span> || <span class="number">2</span> |
| 276 | + <span class="number">-2</span> | <span class="number">-2</span> | <span class="string">"*"</span> || <span class="number">4</span> |
| 277 | + <span class="number">-4</span> | <span class="number">-2</span> | <span class="string">"/"</span> || <span class="number">2</span> |
| 278 | + } |
| 279 | + |
| 280 | + <span class="keyword">def</span> <span class="string">"Test calculate method with division by zero"</span>() { |
| 281 | + <span class="keyword">given:</span> <span class="comment">"A calculator instance"</span> |
| 282 | + <span class="keyword">def</span> calculator = <span class="keyword">new</span> <span class="class-name">Calculator</span>() |
| 283 | + |
| 284 | + <span class="keyword">when:</span> <span class="comment">"Perform division by zero"</span> |
| 285 | + calculator.calculate(<span class="number">10</span>, <span class="number">0</span>, <span class="string">"/"</span>) |
| 286 | + |
| 287 | + <span class="keyword">then:</span> <span class="comment">"An IllegalArgumentException is thrown"</span> |
| 288 | + <span class="keyword">def</span> exception = thrown(<span class="class-name">IllegalArgumentException</span>) |
| 289 | + |
| 290 | + <span class="keyword">and:</span> <span class="comment">"The exception message is correct"</span> |
| 291 | + exception.message == <span class="string">"Cannot divide by zero"</span> |
| 292 | + } |
| 293 | + |
| 294 | + <span class="keyword">def</span> <span class="string">"Test calculate method with invalid operation"</span>() { |
| 295 | + <span class="keyword">given:</span> <span class="comment">"A calculator instance"</span> |
| 296 | + <span class="keyword">def</span> calculator = <span class="keyword">new</span> <span class="class-name">Calculator</span>() |
| 297 | + |
| 298 | + <span class="keyword">when:</span> <span class="comment">"Perform calculation with invalid operation"</span> |
| 299 | + calculator.calculate(<span class="number">1</span>, <span class="number">2</span>, <span class="string">"**"</span>) |
| 300 | + |
| 301 | + <span class="keyword">then:</span> <span class="comment">"An IllegalArgumentException is thrown"</span> |
| 302 | + <span class="keyword">def</span> exception = thrown(<span class="class-name">IllegalArgumentException</span>) |
| 303 | + |
| 304 | + <span class="keyword">and:</span> <span class="comment">"The exception message is correct"</span> |
| 305 | + exception.message == <span class="string">"Invalid operation: **"</span> |
| 306 | + } |
| 307 | +} |
| 308 | + |
| 309 | + |
| 310 | +<span class="comment">// Calculator.groovy</span> |
| 311 | +<span class="keyword">class</span> <span class="class-name">Calculator</span> { |
| 312 | +<span class="comment"> /** |
| 313 | + * Performs arithmetic operations on two integers. |
| 314 | + * |
| 315 | + * <span class="annotation">@param</span> a The first integer. |
| 316 | + * <span class="annotation">@param</span> b The second integer. |
| 317 | + * <span class="annotation">@param</span> operation The operation to perform (+, -, *, /). |
| 318 | + * <span class="annotation">@return</span> The result of the operation. |
| 319 | + * <span class="annotation">@throws</span> IllegalArgumentException if the operation is invalid or division by zero is attempted. |
| 320 | + */</span> |
| 321 | + <span class="keyword">int</span> calculate(<span class="keyword">int</span> a, <span class="keyword">int</span> b, <span class="class-name">String</span> operation) { |
| 322 | + <span class="keyword">switch</span> (operation) { |
| 323 | + <span class="keyword">case</span> <span class="string">"+"</span>: <span class="keyword">return</span> a + b |
| 324 | + <span class="keyword">case</span> <span class="string">"-"</span>: <span class="keyword">return</span> a - b |
| 325 | + <span class="keyword">case</span> <span class="string">"*"</span>: <span class="keyword">return</span> a * b |
| 326 | + <span class="keyword">case</span> <span class="string">"/"</span>: |
| 327 | + <span class="keyword">if</span> (b == <span class="number">0</span>) { |
| 328 | + <span class="keyword">throw</span> <span class="keyword">new</span> <span class="class-name">IllegalArgumentException</span>(<span class="string">"Cannot divide by zero"</span>) |
| 329 | + } |
| 330 | + <span class="keyword">return</span> a / b |
| 331 | + <span class="keyword">default</span>: |
| 332 | + <span class="keyword">throw</span> <span class="keyword">new</span> <span class="class-name">IllegalArgumentException</span>(<span class="string">"Invalid operation: "</span> + operation) |
| 333 | + } |
| 334 | + } |
| 335 | +} |
| 336 | +</code></pre> |
| 337 | + <p class="text-center text-gray-400 mt-6" data-aos="fade-up" data-aos-delay="200"> |
| 338 | + Spock's clear <code class="inline-code">given:</code>, <code class="inline-code">when:</code>, <code class="inline-code">then:</code> blocks make understanding test logic intuitive. |
| 339 | + </p> |
265 | 340 | </div> |
266 | 341 | </div> |
267 | 342 | </section> |
268 | 343 |
|
269 | | -<section class="py-12"> |
270 | | - <div class="container mx-auto px-6 text-center text-gray-400 text-sm additional-links flex flex-wrap justify-center items-center gap-y-2"> |
271 | | - <a href="https://spockframework.org/spock/javadoc/current" target="_blank" class="hover-underline-animation mx-3"><span class="link-separator">Javadoc</span></a> |
272 | | - <a href="https://github.com/spockframework/spock" target="_blank" class="hover-underline-animation mx-3"><span class="link-separator">Source Code</span></a> |
273 | | - <a href="https://github.com/spockframework/spock/issues" target="_blank" class="hover-underline-animation mx-3"><span class="link-separator">Issue Tracker</span></a> |
274 | | - <a href="https://github.com/spockframework/spock/discussions" target="_blank" class="hover-underline-animation mx-3"><span class="link-separator">Discussions</span></a> |
275 | | - <a href="https://gitter.im/spockframework/spock" target="_blank" class="hover-underline-animation mx-3"><span class="link-separator">Chat</span></a> |
276 | | - </div> |
| 344 | +<section class="py-12 bg-gray-800"> <div class="container mx-auto px-6 text-center text-gray-400 text-sm additional-links flex flex-wrap justify-center items-center gap-y-2"> |
| 345 | + <a href="https://spockframework.org/spock/javadoc/current" class="hover-underline-animation mx-3"><span class="link-separator">Javadoc</span></a> |
| 346 | + <a href="https://github.com/spockframework/spock" class="hover-underline-animation mx-3"><span class="link-separator">Source Code</span></a> |
| 347 | + <a href="https://github.com/spockframework/spock/issues" class="hover-underline-animation mx-3"><span class="link-separator">Issue Tracker</span></a> |
| 348 | + <a href="https://github.com/spockframework/spock/discussions" class="hover-underline-animation mx-3"><span class="link-separator">Discussions</span></a> |
| 349 | + <a href="https://gitter.im/spockframework/spock" class="hover-underline-animation mx-3"><span class="link-separator">Discussion Chat</span></a> |
| 350 | +</div> |
277 | 351 | </section> |
278 | 352 |
|
279 | | -<footer class="py-8 text-center text-gray-400 text-sm bg-gray-800"> |
280 | | -<div class="container mx-auto px-6"> |
| 353 | +<footer class="py-8 text-center text-gray-400 text-sm"> |
| 354 | + <div class="container mx-auto px-6"> |
281 | 355 | © 2025 Spock Framework Team. All rights reserved. |
282 | 356 | </div> |
283 | 357 | </footer> |
|
0 commit comments