1818 */
1919package org .netbeans .jdk .fallback .lang ;
2020
21+ import java .util .NoSuchElementException ;
2122import java .util .concurrent .atomic .AtomicBoolean ;
23+ import java .util .concurrent .atomic .AtomicInteger ;
2224import java .util .concurrent .atomic .AtomicReference ;
2325import java .util .function .Supplier ;
2426import org .junit .Test ;
2830
2931public class NBLazyConstantTest {
3032
33+ // true if fallback or JDK 27 impl active
34+ private static final boolean JDK27_SPEC = Runtime .version ().feature () >= 27 || Runtime .version ().feature () < 25 ;
35+
3136 @ Test
3237 public void testFactory () {
3338
@@ -58,29 +63,60 @@ public void testConstant() {
5863 @ Test
5964 public void testRequireNPEOnNullResult () {
6065
61- // StableValue allows null, we use the LazyConstant spec
62- assumeTrue (Runtime .version ().feature () != 25 );
66+ // StableValue allows null, we use the LazyConstant JDK 27 spec
67+ // since its the least permissive
68+ assumeTrue ("jdk 25 impl supports null" , Runtime .version ().feature () != 25 );
6369
6470 AtomicReference <Object > value = new AtomicReference <>();
71+ AtomicInteger calls = new AtomicInteger ();
6572
66- Supplier <Object > lazy = NBLazyConstant .of (() -> value .get ());
73+ Supplier <Object > lazy = NBLazyConstant .of (() -> {
74+ calls .incrementAndGet ();
75+ return value .get ();
76+ });
6777 assertNotNull (lazy );
6878
6979 try {
7080 lazy .get ();
7181 fail ();
72- } catch (NullPointerException good ) {}
82+ } catch (NoSuchElementException good ) {
83+ assertTrue (JDK27_SPEC );
84+ assertEquals (NullPointerException .class , good .getCause ().getClass ());
85+ } catch (NullPointerException good ) {
86+ assertFalse (JDK27_SPEC );
87+ }
88+ assertEquals (1 , calls .get ());
7389
7490 try {
7591 lazy .get ();
7692 fail ();
77- } catch (NullPointerException stillGood ) {}
93+ } catch (NoSuchElementException stillGood ) {
94+ assertTrue (JDK27_SPEC );
95+ // no cause anymore
96+ } catch (NullPointerException stillGood ) {
97+ assertFalse (JDK27_SPEC );
98+ }
99+
100+ // JDK 25-26 spec has retries, we don't test those since fallback mimics JDK 27
101+ if (Runtime .version ().feature () == 26 ) {
102+ return ;
103+ }
104+
105+ assertEquals (1 , calls .get ());
78106
79107 value .set ("good" );
80108
81- // constant can be computed from now on
82- assertEquals ("good" , lazy .get ());
83- assertEquals ("good" , lazy .get ());
109+ // JDK 27+ spec -> no recovery from error state
110+ try {
111+ lazy .get ();
112+ fail ();
113+ } catch (NoSuchElementException stillGood ) {
114+ assertTrue (JDK27_SPEC );
115+ } catch (NullPointerException stillGood ) {
116+ assertFalse (JDK27_SPEC );
117+ }
118+ assertEquals (1 , calls .get ());
119+
84120 }
85121
86122 @ Test
@@ -100,18 +136,41 @@ public void testExceptionDuringCompute() {
100136 try {
101137 lazy .get ();
102138 fail ();
103- } catch (RuntimeException good ) {}
139+ } catch (NoSuchElementException good ) {
140+ assertTrue (JDK27_SPEC );
141+ assertEquals (RuntimeException .class , good .getCause ().getClass ());
142+ } catch (RuntimeException good ) {
143+ assertFalse (JDK27_SPEC );
144+ assertEquals (RuntimeException .class , good .getClass ());
145+ }
104146
105147 try {
106148 lazy .get ();
107149 fail ();
108- } catch (RuntimeException stillGood ) {}
150+ } catch (NoSuchElementException good ) {
151+ assertTrue (JDK27_SPEC );
152+ // no cause anymore
153+ } catch (RuntimeException good ) {
154+ assertFalse (JDK27_SPEC );
155+ assertEquals (RuntimeException .class , good .getClass ());
156+ }
109157
110158 fail .set (false );
111159
112- // constant can be computed from now on
113- assertEquals ("good" , lazy .get ());
114- assertEquals ("good" , lazy .get ());
160+ // we don't test error recovery of 25 and 26
161+ if (!JDK27_SPEC ) {
162+ // assertEquals("good", lazy.get());
163+ // assertEquals("good", lazy.get());
164+ return ;
165+ }
166+
167+ try {
168+ lazy .get ();
169+ fail ();
170+ } catch (RuntimeException stillInFailureState ) {
171+ assertEquals (NoSuchElementException .class , stillInFailureState .getClass ());
172+ }
173+
115174 }
116175
117176}
0 commit comments