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.