dtonhofer
Functional Programming in Java, Second Edition: Functional Programming in Java, Second Edition: JUnit code improvements for Chapter 11, pages 185 ff “Refactoring Unbounded Loops”
The same remarks apply as for “Refactoring the Traditional for Loop”
- No init()
- Negative tests which apply for input less than 1900, resulting in exceptions.
but we cannot implement a common interface as the method parameters change. So we wrap the new class into a class that obeys the old interface, which agains llaows us to use the same test code to test both odl and new classes.
There is also a little tweak to the semantics of the case where 1900 is already rejected - instead of returning 0, we throw. Because there basically is no result in that case.
package chapter11;
import org.junit.jupiter.api.Test;
import java.time.Year;
import java.util.function.Predicate;
import java.util.stream.IntStream;
import static org.junit.jupiter.api.Assertions.*;
public class UnboundedLoopTest {
interface Continue {
boolean check(int year);
}
interface WithContinue {
int countFrom1900(final Continue shouldContinue);
}
static class LeapYearsUnboundedBefore implements WithContinue {
public int countFrom1900(final Continue shouldContinue) {
if (!shouldContinue.check(1900)) {
throw new IllegalArgumentException("Cannot 'continue' right at the start!'");
}
int count = 0;
for (int year = 1900; ; year += 4) {
if (!shouldContinue.check(year)) {
break;
}
if (Year.isLeap(year)) {
count++;
}
}
return count;
}
}
// Does NOT implement WithContinue!!
static class LeapYearsUnboundedAfter {
public int countFrom1900(final Predicate<Integer> shouldContinue) {
if (!shouldContinue.test(1900)) {
throw new IllegalArgumentException("Cannot 'continue' right at the start!'");
}
return (int) IntStream.iterate(1900, year -> year + 4)
.takeWhile(shouldContinue::test)
.filter(Year::isLeap)
.count();
}
}
static class LeapYearsUnboundedAfterWrapped implements WithContinue {
private final LeapYearsUnboundedAfter ly;
public LeapYearsUnboundedAfterWrapped(LeapYearsUnboundedAfter ly) {
this.ly = ly;
}
public int countFrom1900(final Continue shouldContinue) {
return ly.countFrom1900(year -> shouldContinue.check(year));
}
}
// One should maybe have a separate method to test the throws
private static void commonLeapYearsTests(final WithContinue withContinue) {
assertAll(
() -> assertEquals(0, withContinue.countFrom1900(year -> year <= 1900)),
() -> assertEquals(25, withContinue.countFrom1900(year -> year <= 2000)),
() -> assertEquals(27, withContinue.countFrom1900(year -> year <= 2010)),
() -> assertEquals(31, withContinue.countFrom1900(year -> year <= 2025)),
() -> assertEquals(49, withContinue.countFrom1900(year -> year <= 2100)),
() -> assertEquals(267, withContinue.countFrom1900(year -> year <= 3000)),
() -> assertThrows(IllegalArgumentException.class, () ->
withContinue.countFrom1900(year -> year < 1800)
),
() -> assertThrows(IllegalArgumentException.class, () ->
withContinue.countFrom1900(year -> year < 1900)
)
);
}
@Test
void leapYearCountBefore() {
commonLeapYearsTests(new LeapYearsUnboundedBefore());
}
@Test
void leapYearCountAfter() {
commonLeapYearsTests(new LeapYearsUnboundedAfterWrapped(new LeapYearsUnboundedAfter()));
}
}
Popular Pragmatic Bookshelf topics
Running the examples in chapter 5 c under pytest 5.4.1 causes an AttributeError: ‘module’ object has no attribute ‘config’.
In particula...
New
Title: Design and Build Great Web APIs - typo “https://company-atk.herokuapp.com/2258ie4t68jv” (page 19, third bullet in URL list)
Typo:...
New
Hello! Thanks for the great book.
I was attempting the Trie (chap 17) exercises and for number 4 the solution provided for the autocorre...
New
I ran this command after installing the sample application:
$ cards add do something --owner Brian
And got a file not found error:
Fil...
New
“The ProductLive.Index template calls a helper function, live_component/3, that in turn calls on the modal component. ”
Excerpt From: Br...
New
When trying to run tox in parallel as explained on page 151, I got the following error:
tox: error: argument -p/–parallel: expected one...
New
Hey there,
I’m enjoying this book and have learned a few things alredayd. However, in Chapter 4 I believe we are meant to see the “>...
New
Title: Agile Web Development with Rails 7: (page 70)
I am running windows 11 pro with rails 7.0.3 and ruby 3.1.2p20 (2022-04-12 revision...
New
@mfazio23
I’m following the indications of the book and arriver ad chapter 10, but the app cannot be compiled due to an error in the Bas...
New
Hello @herbert ! Trying to get the very first “Hello, Bracket Terminal!" example to run (p. 53). I develop on an Amazon EC2 instance runn...
New
Other popular topics
Ruby, Io, Prolog, Scala, Erlang, Clojure, Haskell. With Seven Languages in Seven Weeks, by Bruce A. Tate, you’ll go beyond the syntax—and...
New
Which, if any, games do you play? On what platform?
I just bought (and completed) Minecraft Dungeons for my Nintendo Switch. Other than ...
New
I am thinking in building or buy a desktop computer for programing, both professionally and on my free time, and my choice of OS is Linux...
New
Design and develop sophisticated 2D games that are as much fun to make as they are to play. From particle effects and pathfinding to soci...
New
From finance to artificial intelligence, genetic algorithms are a powerful tool with a wide array of applications. But you don't need an ...
New
We have a thread about the keyboards we have, but what about nice keyboards we come across that we want? If you have seen any that look n...
New
I have seen the keycaps I want - they are due for a group-buy this week but won’t be delivered until October next year!!! :rofl:
The Ser...
New
This looks like a stunning keycap set :orange_heart:
A LEGENDARY KEYBOARD LIVES ON
When you bought an Apple Macintosh computer in the e...
New
Explore the power of Ash Framework by modeling and building the domain for a real-world web application.
Rebecca Le @sevenseacat and ...
New
Fight complexity and reclaim the original spirit of agility by learning to simplify how you develop software. The result: a more humane a...
New
Categories:
Sub Categories:
Popular Portals
- /elixir
- /rust
- /wasm
- /ruby
- /erlang
- /phoenix
- /keyboards
- /python
- /js
- /rails
- /security
- /go
- /swift
- /vim
- /clojure
- /java
- /emacs
- /haskell
- /svelte
- /onivim
- /typescript
- /kotlin
- /c-plus-plus
- /crystal
- /tailwind
- /react
- /gleam
- /ocaml
- /elm
- /flutter
- /vscode
- /ash
- /html
- /opensuse
- /zig
- /deepseek
- /centos
- /php
- /scala
- /react-native
- /lisp
- /sublime-text
- /textmate
- /debian
- /nixos
- /agda
- /django
- /deno
- /kubuntu
- /arch-linux
- /nodejs
- /ubuntu
- /revery
- /manjaro
- /spring
- /julia
- /diversity
- /lua
- /markdown
- /slackware









