This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new 5fedb798a4 Finalize markdown parser fixes and close TODO-9
5fedb798a4 is described below

commit 5fedb798a48d7ea6e56847de2d965121fba02997
Author: James Bognar <[email protected]>
AuthorDate: Fri May 22 11:04:34 2026 -0400

    Finalize markdown parser fixes and close TODO-9
---
 .../juneau/markdown/MarkdownParserSession.java     | 10 ++++-
 .../a/rttests/RoundTripAddClassAttrs_Test.java     | 12 ++----
 .../juneau/a/rttests/RoundTripBeanMaps_Test.java   | 20 ----------
 .../juneau/commons/runtime/ManifestFile_Test.java  |  6 ++-
 ....md => FINISHED-9-markdown-remaining-issues.md} | 44 ++++++++++++++++++++--
 todo/TODO.md                                       |  2 -
 6 files changed, 55 insertions(+), 39 deletions(-)

diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/markdown/MarkdownParserSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/markdown/MarkdownParserSession.java
index 128c769269..1e490f2fc8 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/markdown/MarkdownParserSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/markdown/MarkdownParserSession.java
@@ -389,7 +389,10 @@ public class MarkdownParserSession extends 
ReaderParserSession {
                                        continue;
                                var rawKey = cells.get(0);
                                var key = parseCellValue(rawKey, keyType, null);
-                               var val = parseCellValue(cells.get(1), 
valueType, null);
+                               // Pass the map being built as the outer when 
parsing values - non-static inner
+                               // classes whose enclosing class is the map 
type (e.g. H1 inside H extends LinkedHashMap)
+                               // need that map instance to satisfy their 
implicit outer-class constructor argument.
+                               var val = parseCellValue(cells.get(1), 
valueType, map);
                                try {
                                        setName(valueType, val, key);
                                } catch (Exception e) {
@@ -556,7 +559,10 @@ public class MarkdownParserSession extends 
ReaderParserSession {
                                        continue;
                                var key = convertAttrToType(map, header, 
keyType);
                                var rawVal = i < cells.size() ? cells.get(i) : 
null;
-                               var val = parseCellValue(rawVal, valueType, 
null);
+                               // Pass the map being built as the outer when 
parsing values - mirrors the
+                               // key-value-table branch so non-static inner 
classes whose enclosing class is the
+                               // map type can be instantiated correctly.
+                               var val = parseCellValue(rawVal, valueType, 
map);
                                map.put(key, val);
                        }
                        return map;
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripAddClassAttrs_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripAddClassAttrs_Test.java
index c40fe5480f..ce469e8f9d 100755
--- 
a/juneau-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripAddClassAttrs_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripAddClassAttrs_Test.java
@@ -179,10 +179,6 @@ class RoundTripAddClassAttrs_Test extends TestBase {
                return t.getParser() instanceof RdfStreamParser;
        }
 
-       private static boolean isMarkdown(RoundTrip_Tester t) {
-               return t.getParser() instanceof MarkdownParser;
-       }
-
        
//====================================================================================================
        // testBean
        
//====================================================================================================
@@ -284,8 +280,6 @@ class RoundTripAddClassAttrs_Test extends TestBase {
        @ParameterizedTest
        @MethodSource("testers")
        void a04_mapsWithTypeParams(RoundTrip_Tester t) throws Exception {
-               if (isMarkdown(t))
-                       return;  // Nested Map parsing returns JsonMap
                var x = new C("foo");
                x = t.roundTrip(x, C.class);
                assertBean(x, 
"f3a{foo{f1}},f3b{foo{f1}},f3c{foo{f1}},f3d{foo{f1}}", 
"{{foo}},{{foo}},{{foo}},{{foo}}");
@@ -318,7 +312,7 @@ class RoundTripAddClassAttrs_Test extends TestBase {
        @ParameterizedTest
        @MethodSource("testers")
        void a05_mapsWithoutTypeParams(RoundTrip_Tester t) throws Exception {
-               if (isRdfStream(t) || isMarkdown(t))
+               if (isRdfStream(t))
                        return;
 
                var x = new D("foo");
@@ -353,7 +347,7 @@ class RoundTripAddClassAttrs_Test extends TestBase {
        @ParameterizedTest
        @MethodSource("testers")
        void a06_beanWithListProps(RoundTrip_Tester t) throws Exception {
-               if (isRdfStream(t) || isMarkdown(t))
+               if (isRdfStream(t))
                        return;
 
                var x = new E("foo");
@@ -388,7 +382,7 @@ class RoundTripAddClassAttrs_Test extends TestBase {
        @ParameterizedTest
        @MethodSource("testers")
        void a07_beanWithListOfArraysProps(RoundTrip_Tester t) throws Exception 
{
-               if (isRdfStream(t) || isMarkdown(t))
+               if (isRdfStream(t))
                        return;
 
                var x = new F("foo");
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMaps_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMaps_Test.java
index fa9d8a01b0..48301f9dd3 100755
--- 
a/juneau-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMaps_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMaps_Test.java
@@ -178,10 +178,6 @@ class RoundTripBeanMaps_Test extends TestBase {
                return RoundTrip_Tester.create(index, 
label).annotatedClasses(L2Config.class, 
M2Config.class).implClasses(m(IBean.class, CBean.class));
        }
 
-       private static boolean isMarkdown(RoundTrip_Tester t) {
-               return t.getParser() instanceof MarkdownParser;
-       }
-
        
//====================================================================================================
        // IBean/ABean/Bean
        
//====================================================================================================
@@ -247,8 +243,6 @@ class RoundTripBeanMaps_Test extends TestBase {
        @ParameterizedTest
        @MethodSource("testers")
        void a04_implMap(RoundTrip_Tester t) throws Exception {
-               if (isMarkdown(t))
-                       return;  // Inline JSON5 in key-value cells needs 
implClass for Map values
                var l = m("foo",new CBean());
 
                l.get("foo").setF1("bar");
@@ -271,8 +265,6 @@ class RoundTripBeanMaps_Test extends TestBase {
        @ParameterizedTest
        @MethodSource("testers")
        void a05_implMap2(RoundTrip_Tester t) throws Exception {
-               if (isMarkdown(t))
-                       return;  // @BeanIgnore / getter-only properties
                var b = new A(1);
                b = t.roundTrip(b);
                if (t.returnOriginalObject || t.getParser() == null)
@@ -786,8 +778,6 @@ class RoundTripBeanMaps_Test extends TestBase {
        @ParameterizedTest
        @MethodSource("testers")
        void a16_memberClass(RoundTrip_Tester t) {
-               if (isMarkdown(t))
-                       return;  // Inner class G1 needs outer instance for 
construction
                var x = G.create();
                assertDoesNotThrow(()->t.roundTrip(x, G.class));
        }
@@ -829,8 +819,6 @@ class RoundTripBeanMaps_Test extends TestBase {
        @ParameterizedTest
        @MethodSource("testers")
        void a17_memberClassWithMapClass(RoundTrip_Tester t) {
-               if (isMarkdown(t))
-                       return;  // Inner class H1 needs outer instance for 
construction
                var x = H.create();
                assertDoesNotThrow(()->t.roundTrip(x, H.class));
        }
@@ -872,8 +860,6 @@ class RoundTripBeanMaps_Test extends TestBase {
        @ParameterizedTest
        @MethodSource("testers")
        void a18_memberClassWithListClass(RoundTrip_Tester t) {
-               if (isMarkdown(t))
-                       return;  // Inner class I1$I2 needs outer instance for 
construction
                var x = I.create();
                assertDoesNotThrow(()->t.roundTrip(x, I.class));
        }
@@ -915,8 +901,6 @@ class RoundTripBeanMaps_Test extends TestBase {
        @ParameterizedTest
        @MethodSource("testers")
        void a19_memberClassWithStringConstructor(RoundTrip_Tester t) {
-               if (isMarkdown(t))
-                       return;  // J2 has string constructor, serialized as 
'2' in backticks
                var x = J.create();
                assertDoesNotThrow(()->t.roundTrip(x, J.class));
        }
@@ -1020,8 +1004,6 @@ class RoundTripBeanMaps_Test extends TestBase {
        @ParameterizedTest
        @MethodSource("testers")
        void a22_wrapperAttrAnnotationOnBean_usingConfig(RoundTrip_Tester t) {
-               if (isMarkdown(t))
-                       return;  // Map with Key/Value headers vs bean with 
wrapperAttr
                var x = L2.create();
                assertDoesNotThrow(()->t.roundTrip(x, L2.class));
 
@@ -1083,8 +1065,6 @@ class RoundTripBeanMaps_Test extends TestBase {
        @ParameterizedTest
        @MethodSource("testers")
        void a24_WrapperAttrAnnotationOnNonBean_usingConfig(RoundTrip_Tester t) 
{
-               if (isMarkdown(t))
-                       return;  // Map with Key/Value headers vs non-bean with 
wrapperAttr
                var x = M2.create();
                assertDoesNotThrow(()->t.roundTrip(x, M2.class));
 
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/commons/runtime/ManifestFile_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/commons/runtime/ManifestFile_Test.java
index b382427669..26e7ae2101 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/commons/runtime/ManifestFile_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/commons/runtime/ManifestFile_Test.java
@@ -72,7 +72,8 @@ class ManifestFile_Test extends TestBase {
 
        @Test void a04_asMapUnmodifiable() {
                var x = new ManifestFile(mainManifest());
-               assertThrows(UnsupportedOperationException.class, () -> 
x.asMap().put("k", "v"));
+               var map = x.asMap();
+               assertThrows(UnsupportedOperationException.class, () -> 
map.put("k", "v"));
        }
 
        
//-----------------------------------------------------------------------------------------------------------------
@@ -111,7 +112,8 @@ class ManifestFile_Test extends TestBase {
 
        @Test void b06_sectionMapUnmodifiable() {
                var x = new ManifestFile(manifestWithSections());
-               assertThrows(UnsupportedOperationException.class, () -> 
x.asMap("my-section").put("k", "v"));
+               var map = x.asMap("my-section");
+               assertThrows(UnsupportedOperationException.class, () -> 
map.put("k", "v"));
        }
 
        
//-----------------------------------------------------------------------------------------------------------------
diff --git a/todo/TODO-9-markdown-remaining-issues.md 
b/todo/FINISHED-9-markdown-remaining-issues.md
similarity index 70%
rename from todo/TODO-9-markdown-remaining-issues.md
rename to todo/FINISHED-9-markdown-remaining-issues.md
index 9f2cb0f9e7..3fba2f3cce 100644
--- a/todo/TODO-9-markdown-remaining-issues.md
+++ b/todo/FINISHED-9-markdown-remaining-issues.md
@@ -1,9 +1,45 @@
-# Markdown Round-Trip: Remaining Issues
+# Markdown Round-Trip: Remaining Issues (Finished)
 
-This document tracks the tests that are currently skipped for the Markdown 
tester (tester [22])
-and describes what would be required to fix each one.
+This document tracks the tests that *were* skipped for the Markdown tester 
(tester [23] in
+`RoundTripBeanMaps_Test`, tester [25] in `RoundTripAddClassAttrs_Test`) and 
the fixes that closed
+each one. **All six issues are now closed and all round-trip tests pass.**
 
-All other round-trip tests pass as of the current implementation.
+## Outcome summary
+
+| Test(s) | Original Issue | Resolution |
+|---------|----------------|------------|
+| `BeanMaps.a04` | `implClass` not copied to embedded `Json5Parser` | Already 
worked — `marshallingContext((MarshallingContext) getContext())` shares the 
parent context (and hence the impl-class registry) with the embedded 
`Json5Parser`. Only the skip guard needed removal. |
+| `BeanMaps.a05` | `@BeanIgnore` / getter-type mismatch | Already worked — the 
`needsJson5Path()` classification + shared bean context already routed `A` 
through the JSON5 path correctly. Only the skip guard needed removal. |
+| `BeanMaps.a16, a18, a19` | Non-static inner classes (G/G1/G2, I/I1/I2, J/J2) 
need outer propagation | Already worked — the `parseRow()` / 
`parseKeyValueTable()` bean branches were already passing `m.getBean(false)` as 
the outer when recursing into nested cells, which is sufficient for the G/I/J 
cases. Only the skip guards needed removal. |
+| `BeanMaps.a17` | Inner classes inside a `Map`-extending bean (H/H1/H2) need 
outer propagation through the map | **Production fix** — 
`parseKeyValueTable()`'s map branch and `parseRow()`'s map branch were passing 
`null` as the outer when parsing each value cell. They now pass the 
partially-built `map` instance, so a non-static inner class whose enclosing 
class **is** the map type (e.g. `H1` inside `H extends LinkedHashMap`) can 
resolve its synthetic `$outer` constructor argument correctly. |
+| `BeanMaps.a22, a24` | Config-annotation `@WrapperAttr` not seen by embedded 
serializer | Already worked — same root cause as A3: the 
`marshallingContext((MarshallingContext) getContext())` plumbing carries 
config-annotation registrations into the embedded `Json5Serializer`. Only the 
skip guards needed removal. |
+| `AddClassAttrs.a04–a07` | `_type` in multi-column tables not resolved for 
`Object` element type | Already worked — the existing `cast(m, null, eType)` 
call at the end of the Object branch in `parseRow()` already resolves 
`_type`-discriminated rows via the bean registry. Only the skip guards needed 
removal. |
+
+## Fixed in this pass
+
+### Production code
+
+- 
`juneau-core/juneau-marshall/src/main/java/org/apache/juneau/markdown/MarkdownParserSession.java`
+  - `parseKeyValueTable()` (line ~392): pass the in-progress `map` as the 
outer when parsing each value cell, replacing the previous `null`.
+  - `parseRow()` map branch (line ~563): same change for the multi-column 
path, for consistency.
+
+### Test code (skip guards removed)
+
+- 
`juneau-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMaps_Test.java`
+  - `a04_implMap`, `a05_implMap2`, `a16_memberClass`, 
`a17_memberClassWithMapClass`, `a18_memberClassWithListClass`, 
`a19_memberClassWithStringConstructor`, 
`a22_wrapperAttrAnnotationOnBean_usingConfig`, 
`a24_WrapperAttrAnnotationOnNonBean_usingConfig`: removed `if (isMarkdown(t)) 
return;` guards.
+- 
`juneau-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripAddClassAttrs_Test.java`
+  - `a04_mapsWithTypeParams`: removed `if (isMarkdown(t)) return;` guard.
+  - `a05_mapsWithoutTypeParams`, `a06_beanWithListProps`, 
`a07_beanWithListOfArraysProps`: removed the `|| isMarkdown(t)` part of the 
skip-guard expression while keeping the `isRdfStream(t)` skip.
+
+## Verification
+
+- `mvn -pl juneau-utest -am test -Dtest='RoundTrip*' -Drat.skip=true 
-Dsurefire.failIfNoSpecifiedTests=false` — 2264 tests pass, 0 failures, 0 
errors (18 skipped from unrelated `RoundTripBeanChannel_Test` / 
`RoundTripLargeObjects_Test` guards that pre-date this work).
+- `mvn -pl juneau-utest -am test -Dtest='*Markdown*' -Drat.skip=true 
-Dsurefire.failIfNoSpecifiedTests=false` — 116 Markdown-specific tests pass, 0 
failures.
+- `./scripts/test.py` — full clean build + test pass.
+
+---
+
+## Original issue analysis (kept for historical context)
 
 ---
 
diff --git a/todo/TODO.md b/todo/TODO.md
index 0b1d64ab24..4a9a5f70db 100644
--- a/todo/TODO.md
+++ b/todo/TODO.md
@@ -3,8 +3,6 @@
 
 - [TODO-7] Decouple `juneau-rest-common` from `juneau-marshall` by breaking 
the compile dependency so REST annotations and beans can be used without 
pulling in the full serialization stack. See 
`todo/TODO-7-decouple-rest-common-from-marshall.md`.
 
-- [TODO-9] Fix remaining skipped Markdown round-trip test cases (tables, 
nested structures, edge cases). See `todo/TODO-9-markdown-remaining-issues.md`.
-
 - [TODO-14] Close the latent map-key coercion gap in 
`BeanPropertyMeta.setPropertyValue` (`needsConversion` predicate inspects only 
entry values, not entry keys; key-side `convertToType` call missing). Currently 
unreachable from any tested parser thanks to the per-parser Bug #7b fixes, but 
a defense-in-depth backstop. See 
`todo/TODO-14-beanpropertymeta-map-key-coercion.md`.
 
 - [TODO-17] Audit 9.2.x changes (juneau-docs release notes 9.2.0 / 9.5.0 + git 
history since 9.1.0) for breaking changes and populate the v9.5 Migration Guide 
at juneau-docs/pages/topics/23.01.V9.5-migration-guide.md with Old→New rows for 
each. Focus on removed APIs, renamed annotations/classes/methods, changed 
default behaviors, and any annotation-attribute semantics changes.

Reply via email to