dtonhofer

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())); } } 

Where Next?

Popular Pragmatic Bookshelf topics Top

johnp
Hi Brian, Looks like the api for tinydb has changed a little. Noticed while working on chapter 7 that the .purge() call to the db throws...
New
GilWright
Working through the steps (checking that the Info,plist matches exactly), run the demo game and what appears is grey but does not fill th...
New
mikecargal
Title: Hands-On Rust (Chapter 11: prefab) Just played a couple of amulet-less games. With a bit of debugging, I believe that your can_p...
New
rmurray10127
Title: Intuitive Python: docker run… denied error (page 2) Attempted to run the docker command in both CLI and Powershell PS C:\Users\r...
New
swlaschin
The book has the same “Problem space/Solution space” diagram on page 18 as is on page 17. The correct Problem/Solution space diagrams ar...
New
adamwoolhether
I’m not quite sure what’s going on here, but I’m unable to have to containers successfully complete the Readiness/Liveness checks. I’m im...
New
kolossal
Hi, I need some help, I’m new to rust and was learning through your book. but I got stuck at the last stage of distribution. Whenever I t...
New
Henrai
Hi, I’m working on the Chapter 8 of the book. After I add add the point_offset, I’m still able to see acne: In the image above, I re...
New
jwandekoken
Book: Programming Phoenix LiveView, page 142 (157/378), file lib/pento_web/live/product_live/form_component.ex, in the function below: d...
New
dachristenson
I’ve got to the end of Ch. 11, and the app runs, with all tabs displaying what they should – at first. After switching around between St...
New

Other popular topics Top

DevotionGeo
I know that these benchmarks might not be the exact picture of real-world scenario, but still I expect a Rust web framework performing a ...
New
PragmaticBookshelf
Rust is an exciting new programming language combining the power of C with memory safety, fearless concurrency, and productivity boosters...
New
New
PragmaticBookshelf
Tailwind CSS is an exciting new CSS framework that allows you to design your site by composing simple utility classes to create complex e...
New
New
Help
I am trying to crate a game for the Nintendo switch, I wanted to use Java as I am comfortable with that programming language. Can you use...
New
AstonJ
If you want a quick and easy way to block any website on your Mac using Little Snitch simply… File &gt; New Rule: And select Deny, O...
New
DevotionGeo
I have always used antique keyboards like Cherry MX 1800 or Cherry MX 8100 and almost always have modified the switches in some way, like...
New
PragmaticBookshelf
Explore the power of Ash Framework by modeling and building the domain for a real-world web application. Rebecca Le @sevenseacat and ...
New
RobertRichards
Hair Salon Games for Girls Fun Girls Hair Saloon game is mainly developed for kids. This game allows users to select virtual avatars to ...
New

Latest in Functional Programming in Java, Second Edition

Functional Programming in Java, Second Edition Portal

Sub Categories: